したがって、15個のテーブルにヒットする中規模のクエリがあります。 MySQLでクエリが完了するまでに36秒かかります。クエリでEXPLAINを実行すると、テーブルの1つがこれを返しました。
'1'、 'SIMPLE'、 'mount_adapters'、 'index'、NULL、 'mount_product_ID_2'、 '10'、NULL、 '15841'、 'インデックスの使用;結合バッファの使用 '
したがって、これがクエリの速度を低下させます。テーブルは1つの主キー、2つのint、およびvarchar(2)で構成されていますが、テーブルには4つのインデックスがあります。
インデックス(mount_product_ID_2)を使用しているようですが、使用しているようです。紛らわしいのは、使用できるキーがないと言っているのに、インデックスを使おうとしていることです。
誰かがこれを説明できますか?
コードの更新
Table: mount_adapters
Create Table: CREATE TABLE `mount_adapters` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`mount_product_ID` int(11) NOT NULL,
`adapter_product_ID` int(11) NOT NULL,
`relationship_type` varchar(2) DEFAULT '',
PRIMARY KEY (`ID`),
KEY `mount_product_ID` (`mount_product_ID`),
KEY `adapter_product_ID` (`adapter_product_ID`),
KEY `mount_product_ID_2` (`mount_product_ID`,`adapter_product_ID`),
KEY `adapter_product_ID_2` (`adapter_product_ID`,`mount_product_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=16014 DEFAULT CHARSET=utf8
クエリ
SELECT
SQL_CALC_FOUND_ROWS
DISTINCT (
IF (
dependent_mounts.`ID`,
dependent_mounts.`ID`,
independent_mounts.`ID`
)
) AS 'product_ID'
FROM (
`product_av_models`,
`mount_adapters`
)
LEFT JOIN `av_models` bp ON (
bp.`ID` = `product_av_models`.`av_model_ID`
)
LEFT JOIN `products` independent_mounts ON (
independent_mounts.`ID` = `product_av_models`.`product_ID` AND
independent_mounts.`type_ID` != 11
)
LEFT JOIN `product_countries` independent_mounts_product_countries ON (
independent_mounts_product_countries.`product_ID` = independent_mounts.`ID`
)
LEFT JOIN `countries` independent_mounts_countries ON (
independent_mounts_countries.`ID` = independent_mounts_product_countries.`country_ID`
)
LEFT JOIN `products` adapters ON (
adapters.`ID` = `product_av_models`.`product_ID` AND
adapters.`type_ID` = 11
)
LEFT JOIN `product_countries` adapters_product_countries ON (
adapters_product_countries.`product_ID` = adapters.`ID`
)
LEFT JOIN `countries` adapters_countries ON (
adapters_countries.`ID` = adapters_product_countries.`country_ID`
AND adapters_countries.`code` = 'US'
)
LEFT JOIN `products` dependent_mounts ON (
dependent_mounts.`ID` = `mount_adapters`.`mount_product_ID` AND
`mount_adapters`.`adapter_product_ID` = adapters.`ID`
)
LEFT JOIN `product_countries` dependent_mounts_product_countries ON (
dependent_mounts_product_countries.`product_ID` = dependent_mounts.`ID`
)
LEFT JOIN `countries` dependent_mounts_countries ON (
dependent_mounts_countries.`ID` = dependent_mounts_product_countries.`country_ID`
AND dependent_mounts_countries.`code` = 'US'
)
LEFT JOIN `products_spec_data` dependent_mounts_spec_size_min ON (
dependent_mounts_spec_size_min.`products_spec_name_id` = 12 AND
dependent_mounts_spec_size_min.`products_id` = dependent_mounts.`ID`
)
LEFT JOIN `products_spec_data` dependent_mounts_spec_size_max ON (
dependent_mounts_spec_size_max.`products_spec_name_id` = 13 AND
dependent_mounts_spec_size_max.`products_id` = dependent_mounts.`ID`
)
LEFT JOIN `products_spec_data` dependent_mounts_spec_weight ON (
dependent_mounts_spec_weight.`products_spec_name_id` = 25 AND
dependent_mounts_spec_weight.`products_id` = dependent_mounts.`ID`
)
WHERE `product_av_models`.`av_model_ID` = 12536
AND (
independent_mounts.`ID` IS NULL
OR (
independent_mounts.`group` = 'F'
AND independent_mounts.`active` = 'T'
AND independent_mounts.`display_mountfinder` = 'T'
AND independent_mounts_countries.`code` = 'US'
)
)
AND (
adapters.`ID` IS NULL
OR (
adapters.`group` = 'F'
AND adapters.`active` = 'T'
AND adapters_countries.`code` = 'US'
)
)
AND (
-- IS EXIST here maybe
dependent_mounts.`ID` IS NULL
OR (
dependent_mounts.`group` = 'F'
AND dependent_mounts.`active` = 'T'
AND dependent_mounts.`display_mountfinder` = 'T'
AND dependent_mounts_countries.`code` = 'US'
AND dependent_mounts_spec_size_min.`value` > 0
AND dependent_mounts_spec_size_min.`value` <= bp.`screen_size`
AND dependent_mounts_spec_size_max.`value` > 0
AND dependent_mounts_spec_size_max.`value` >= bp.`screen_size`
AND dependent_mounts_spec_weight.`value` > 0
AND dependent_mounts_spec_weight.`value` >= bp.`screen_weight`
)
)
ORDER BY
independent_mounts.`name` ASC,
dependent_mounts.`name` ASC,
adapters.`name` ASC
完全な説明を提供しなかったため、クエリの速度が低下している原因を正確に特定するのは困難です。ただし、提供されたEXPLAIN出力の意味を説明することはできます。
MySQL EXPLAIN結合タイプ によると、インデックス結合タイプは、クエリが「前のテーブルの行の組み合わせごとに」インデックス全体をスキャンすることを意味します。言い換えれば、それは完全なインデックススキャンを実行していますが、これは良くないかもしれません。
MySQL EXPLAIN結合タイプ に記載されているEXPLAINのExtra列のインデックスを使用すると、テーブルデータ(つまり、MyISAMテーブルの場合はMYDファイル)がまったく読み取られないことを意味します。インデックスには、クエリに必要なすべてのデータが含まれます。
キー列のNULLは、インデックスが行の検索に使用されないことを意味します。
これは、クエリが実際にインデックスツリー全体を歩いていることを意味しますが、インデックスから15k行を読み取ることが、クエリの実際の問題である可能性はありません。