web-dev-qa-db-ja.com

クエリの結果、奇妙な説明出力が表示されます

したがって、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
2
Clutch

完全な説明を提供しなかったため、クエリの速度が低下している原因を正確に特定するのは困難です。ただし、提供されたEXPLAIN出力の意味を説明することはできます。

MySQL EXPLAIN結合タイプ によると、インデックス結合タイプは、クエリが「前のテーブルの行の組み合わせごとに」インデックス全体をスキャンすることを意味します。言い換えれば、それは完全なインデックススキャンを実行していますが、これは良くないかもしれません。

MySQL EXPLAIN結合タイプ に記載されているEXPLAINのExtra列のインデックスを使用すると、テーブルデータ(つまり、MyISAMテーブルの場合はMYDファイル)がまったく読み取られないことを意味します。インデックスには、クエリに必要なすべてのデータが含まれます。

キー列のNULLは、インデックスが行の検索に使用されないことを意味します。

これは、クエリが実際にインデックスツリー全体を歩いていることを意味しますが、インデックスから15k行を読み取ることが、クエリの実際の問題である可能性はありません。

1
redguy