2

構造が次のような特定のロギングテーブルの場合:

CREATE TABLE `example` (
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `quantity` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
  `price` varchar(15) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

エントリが毎分挿入される場合、このテーブルをインデックスなしで残す方が効率的であることを理解しています。ただし、同様のテーブルをと比較しようとすると問題が発生しますSELECT

次のクエリの平均速度は約3.7秒です

SELECT * FROM (
    SELECT `t1`.`time`,
           `t1`.`quantity` AS `q1`,
           `t1`.`price` AS `p1`,
           `t2`.`quantity` AS `q2`,
           `t2`.`price` AS `p2`
    FROM `example 1` AS `t1`,
         `example 2` AS `t2`
    WHERE `t1`.`time` = `t2`.`time`
    ORDER BY `time` DESC LIMIT 72
) AS dt ORDER BY time ASC;

このクエリにかかる時間を大幅に短縮する方法はありますか?同様のクエリ、

SELECT * FROM (
    SELECT *
    FROM `example`
    ORDER BY `time` DESC LIMIT 72
) AS dt ORDER BY time ASC;

たった0.008秒かかります。それで、2つの別々のクエリを実行し、PHPを使用してそれらを比較する方が効率的ですが、はるかに醜いと思います。

4

1 に答える 1

0

これが少し基本的なように思われる場合はご容赦ください。しかし、物事を基本に戻すことで、私の考えが明確になることがわかります。

インデックスはデータを整理する方法であり、データの作成時に支払う代償があります。故障したキャビネットに紙のファイルを保管することを考えてみてください。それらを保管する最も簡単な方法は、それらが収まる場所に詰め込むことですが、後で見つける必要がある場合は、引き出しのすべてのページをチェックする必要があります. 代わりに、日付順に保存したい場合は、それらを入れるのにより多くの時間がかかるが、それらを見つけるのにかかる時間は短くなります.

したがって、トレードオフがあります。インデックスが多いほど、INSERTS は遅くなりますが、DELETES と UPDATES を使用した SELECTS は速くなり、中間のどこかに落ちます。

通常のユーザーが生成/アクセスするテーブルの場合、通常、他の何よりも多くの SELECT があり、より多くの行に触れるため、広範なインデックス作成が示されます。ログ テーブルの場合、より多くの INSERTS が存在するため、インデックスには注意してください。

ただし、作成された順序でレコードをソートするインデックスのオーバーヘッドは、新しいレコードを途中で貼り付ける必要がある場合よりもはるかに少ないため、作成された日時にインデックス付けされたログ テーブルには大きなオーバーヘッドはありません。

また、あなたの場合、1 分あたり 1 レコードは非常に低いレートであるため、オーバーヘッドが問題になる可能性はほとんどありません。毎秒数百というのは、リアルタイムのプラント ロギングでは珍しくありませんが、これは別の問題です。

お役に立てれば。

于 2013-01-14T21:42:50.080 に答える