0

このようなテーブルがあります

CREATE TABLE values (
    id int(10) auto_increment NOT NULL, 
    molecule_id int(5) NOT NULL,
    descriptor_id int(5) NOT NULL,
    T double DEFAULT NULL,
    value double NOT NULL,
    PRIMARY KEY (id),
    KEY index1 (molecule_id, T),
    KEY index2 (descriptor_id, T)
) ENGINE=InnoDB;    

テーブルの行は、3000 の記述子 ID、600 の分子 ID、およびランダムな double 値を持つ 3500 の T の多数の組み合わせです (約 20 億行)。

私は次のようなクエリの場合、という印象を受けました

SELECT T, value FROM values WHERE molecule_id = X AND descriptor_id = Y

mysql は両方のキーを使用し、結果を交差させます。しかし、Explain extendedこのクエリを実行すると、index1 と index2 の間で選択されており、index2 のみが使用されていることがわかります。

Molecule_id = X はテーブルの約 1/600 にヒットします。descriptor_id = Y は、Y に応じて、テーブルのテーブルのごく一部 (0.001% など) または約 1/700 にヒットします。

index2 を使用して残りの約 250 万行をスキャンするよりも、交差する方が高速であるように思われます。3000 の descriptor_id が均等に分散されたとしても、平均で 800,000 行をスキャンする必要があります。

私は何が欠けていますか?

4

2 に答える 2

0

index_merge操作は、少なくとも 1 つのキーに範囲スキャンがある場合にのみ使用されると思います。サンプル クエリには等価述語しかなく、MySQL は範囲スキャンと見なすものは何もありません。

于 2012-07-12T16:25:28.580 に答える
0

spencer7593 はその通りです。index_merge は、範囲の状況でのみ発生します。あなたANDの場合はOR、index_merge をトリガーします。ただし、 であるため、と の両方にANDmulti_column インデックスを作成しないのはなぜですか? これにより、より良い結果が得られ、より速くなります。(あなたが述べたように)より排他的である場合、これを行います:molecule_iddescriptor_iddescriptor_id

ALTER TABLE values ADD INDEX descriptor_molecule (descriptor_id, molecule_id, T, value)

条件付きの where 句に両方の列がある限り、クエリはANDこのインデックスを使用します。この場合、クエリの where 句に列index2しかない場合でも、インデックスをプレフィックス インデックスとして使用できるため、実際には削除します。さらに、4 つの列すべてにインデックスを付けると、言及したクエリのカバリング インデックスが作成されるため、クエリがかなり高速化されます。descriptor_iddescriptor_molecule

于 2012-07-12T16:40:38.643 に答える