11

主キーとして約8つのフィールドを含む非常に大きなテーブル(数百万のレコード)があります。簡単にするために、テーブルは次のようになっているとしましょう。

    key_1 | key_2 | key_3 | ... | key_8 | value

key_1の値が与えられた場合、次の行に沿ってkey_2、key_3、...、key_8のすべての可能な値をフェッチする必要があります。

    SELECT DISTINCT key_2 FROM table1 WHERE key_1 = 123;
    SELECT DISTINCT key_3 FROM table1 WHERE key_1 = 123;
    ...
    SELECT DISTINCT key_8 FROM table1 WHERE key_1 = 123;

私の問題は、このクエリがパフォーマンスのニーズよりも大幅に遅く、このテーブルのデータがかなり一定であり、更新されることはめったにないことです(数日に1回)。また、table_1は遅いサブクエリである可能性があります。データベースに追加のテーブルを作成し、データベースが更新されるたびに手動で更新する以外に、迅速な結果を得ることができる別のソリューションがあります。複数のMySQLセッションで機能するために必要です。

4

2 に答える 2

19

私たちが持っている情報で決定的な答えを出すことはできませんが、これらから始めましょう:

key_1にインデックスがありますか?

これがないと、各クエリ自体は、123を探すだけですでに遅くなります。

(key_1、key_2)にインデックスがありますか?

select distinct key_2 where key_1 = 123インデックスだけから必要なすべてのデータを取得できれば、本当に高速だからです。テーブルにアクセスする必要はありません。

行/インデックスは固定サイズですか?

オフセットを計算するだけでx番目のレコードがどこにあるかが常にわかるため、固定サイズのテーブル/行をトラバースする方が高速です。可変行サイズのテーブルは低速です。

自動インクリメントの代理主キーを追加してみましたか?

インデックスは、列と小さな主キーだけを格納する必要がある場合に、より効果的に機能します。複合主キーは低速です。

読み取り専用テーブルを検討しましたか?

myisamテーブルをパックして高速アクセスできますが、読み取り専用になります。しかし、それはその用途があるハックです。

さらに一歩進んで、データウェアハウスを検討しましたか?

テーブルが頻繁に変更されない場合は、高速アクセスのために情報を複製するのが最適な場合があります。

show create table声明を投稿できますか?列とインデックスを確認すると役立ちます。explain select声明を投稿できますか?どのインデックスが使用されているかを確認すると役立ちます。

于 2012-05-29T13:52:52.787 に答える
4
SELECT DISTINCT key_2 FROM table1 WHERE key_1 = 123;

これにより、主キーインデックス(key_1、key_2など)を使用できます。これにより、テーブルスキャンや一時テーブルよりも高速なインデックススキャンが実行されます。

SELECT DISTINCT key_3 FROM table1 WHERE key_1 = 123;

key_1とkey_3の組み合わせは主キーのプレフィックスを形成しないため、主キーを使用できません。key_1とkey_3にこの順序で複合インデックスを作成する必要があります。次に、そのインデックスを使用して、インデックススキャンも実行できます。

SELECT DISTINCT key_8 FROM table1 WHERE key_1 = 123;

key_1とkey_8の順にインデックスが必要です。同上。

于 2012-05-29T14:21:44.923 に答える