上の全表スキャンは、私は、次のMySQLのテーブル(のみ845行)を持っている:のMySQL - クエリを登録しよう
CREATE TABLE `categories_nested_set` (
`lft` int(11) NOT NULL DEFAULT '0',
`rgt` int(11) DEFAULT NULL,
`id` int(11) DEFAULT NULL,
`category` varchar(128) DEFAULT NULL,
PRIMARY KEY (`lft`),
UNIQUE KEY `id` (`id`),
UNIQUE KEY `rgt` (`rgt`),
KEY `idx_lftrgtid` (`id`,`lft`,`rgt`),
KEY `idx_lft` (`lft`),
KEY `i1` (`lft`) USING BTREE,
KEY `i2` (`rgt`) USING BTREE,
KEY `i3` (`id`) USING BTREE,
CONSTRAINT `fk_categories_nested_set_id_category` FOREIGN KEY (`id`) REFERENCES `categories` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
(私は念のために、そこにインデックスの全体の多くを持って見ることができます)。
私は以下の自己結合クエリを実行します。以下は、EXPLAIN生成
SELECT *
FROM categories_nested_set AS H
LEFT JOIN categories_nested_set AS I ON (H.lft > I.lft)
:
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,H,ALL,NULL,NULL,NULL,NULL,845,NULL
1,SIMPLE,I,ALL,"PRIMARY,idx_lft,i1",NULL,NULL,NULL,845,"Range checked for each record (index map: 0x31)"
をEXPLAINは、MySQLが使用しないように選択されていることを示唆していますインデックス、なぜ私は理解できません。表定義は、関連するすべての列が索引付けされることを示します。
これよりもはるかに大きなクエリ(500万行、14xテーブル)の範囲では、この部分は大きなボトルネックであることが判明しています。アドバイスをいただければ幸いです。
おかげで、
'EXPLAIN'を実行したデータセットに実際には845行しかありませんか?例えば、データセットが十分に小さい場合、MySQLはインデックスを必ずしも使用しません。実際の大規模なクエリでパフォーマンス統計情報を取得する必要があります。 –
はい、845行のみです。異なるものは大きなクエリで説明しますが、はるかに精巧ですが、それでもフルテーブルスキャンです。 – mils
ジョインの左側にある表に対して、少なくとも1つのフル・テーブル・スキャンを実行する必要があります。 –