未应用连接查询索引

Joined query index not applied

我有一个问题:

 SELECT `dsd_prefix`,
      `dsd_partner`,
      `eev1`.`eev_dse_element_name`,
      `devd_explanation`,
      `devd_min`,
      `eev1`.`eev_dev_value`,
      `devd_max`,
      `devd_format`,
      `devd_not_applicable`,
      `devd_not_available`,
      `dsd_nid`
       FROM `devdescription` 
 INNER JOIN ekohubelementvalue AS `eev1`
             ON `eev1`.`eev_dse_element_name` = `devd_element_name`
            AND `eev1`.`eev_prefix` = `devd_prefix`
  LEFT JOIN `ekohubelementvalue` AS `eev2`
               ON `eev1`.`eev_prefix` = `eev2`.`eev_prefix`
              AND `eev1`.`eev_dse_element_name` = `eev2`.`eev_dse_element_name`
              AND `eev1`.`eev_subcategory` = `eev2`.`eev_subcategory`
              AND `eev1`.`eev_company_id` = `eev2`.`eev_company_id`
              AND `eev2`.`eev_date_updated` > `eev1`.`eev_date_updated`
INNER JOIN `datasourcedescription`
               ON `eev1`.`eev_prefix` = `dsd_prefix`
      WHERE (`eev1`.`eev_company_id` = 'ADD4027'
            AND `eev2`.`eev_date_updated` IS NULL
            AND `dsd_type_id` != 'MAJ'
            AND `dsd_hide` = 'No'
            AND (`devd_supress` IS NULL OR `devd_supress` <> 'Yes'))
   GROUP BY `eev1`.`eev_dse_element_name`, `eev1`.`eev_prefix`
   ORDER BY dsd_prefix

此查询的解释:

+----+-------------+-----------------------+------------+------+-----------------------------------------------------------------------------------------------------------------+---------------------+---------+--------------------------------------------------------------------------------------------------------------------------+------+----------+----------------------------------------------+
| id | select_type | table                 | partitions | type | possible_keys                                                                                                   | key                 | key_len | ref                                                                                                                      | rows | filtered | Extra                                        |
+----+-------------+-----------------------+------------+------+-----------------------------------------------------------------------------------------------------------------+---------------------+---------+--------------------------------------------------------------------------------------------------------------------------+------+----------+----------------------------------------------+
|  1 | SIMPLE      | datasourcedescription | NULL       | ALL  | PRIMARY,datasourcedescription_dsd_type_id                                                                       | NULL                | NULL    | NULL                                                                                                                     |  688 |    10.00 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | eev1                  | NULL       | ref  | eev_prefix,eev_company_id,earliest_and_latest,slice_by_date_for_company,sources_for_special_issue               | earliest_and_latest | 47      | csrhub_data_1.datasourcedescription.dsd_prefix                                                                           |  607 |     0.04 | Using where                                  |
|  1 | SIMPLE      | devdescription        | NULL       | ref  | reports,supress,devd_element_name                                                                               | reports             | 816     | csrhub_data_1.datasourcedescription.dsd_prefix,csrhub_data_1.eev1.eev_dse_element_name                                   |    1 |    50.00 | Using where                                  |
|  1 | SIMPLE      | eev2                  | NULL       | ref  | eev_prefix,eev_company_id,earliest_and_latest,slice_by_date,slice_by_date_for_company,sources_for_special_issue | eev_prefix          | 861     | csrhub_data_1.datasourcedescription.dsd_prefix,csrhub_data_1.eev1.eev_dse_element_name,csrhub_data_1.eev1.eev_company_id |   17 |    19.00 | Using where                                  |
+----+-------------+-----------------------+------------+------+-----------------------------------------------------------------------------------------------------------------+---------------------+---------+--------------------------------------------------------------------------------------------------------------------------+------+----------+----------------------------------------------+

如您所见,datasourcedescription 索引虽然存在于 posible_keys 中,但未被使用。 key 列为 NULL。

显示数据源描述中的索引;

+-----------------------+------------+-----------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table                 | Non_unique | Key_name                          | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-----------------------+------------+-----------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| datasourcedescription |          0 | PRIMARY                           |            1 | dsd_prefix  | A         |         688 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| datasourcedescription |          1 | datasourcedescription_dsd_type_id |            1 | dsd_type_id | A         |           8 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+-----------------------+------------+-----------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+

如何让优化器利用 datasourcedescription 索引?

作为对@O 的回应。琼斯: datasourcedescription 列是 dsd_prefixdsd_type_iddsd_hide

table datasourcedescription 有 727 行。 table ekohubelementvalue 有将近 300,000,000 (300M) 行

您提到 ekohubelementvalue 有将近 300 万行。您的 where 子句基于特定的公司 ID。我会稍微重写查询,但还要确保 ekohubelementvalue table 有一个索引,其中公司 ID 位于主要位置,其他列有助于尽可能覆盖 join/wehre 条件。同样对于 MySQL,我会添加“STRAIGHT_JOIN”关键字来告诉 MySQL 按照您提供的顺序进行查询 vs 它猜测哪个顺序。

我会有以下索引可用

ekohubelementvalue index on ( eev_company_id, eev_prefix, eev_dse_element_name, eev_subcategory, eev_date_updated )
devdescription index on ( devd_element_name, devd_prefix, devd_supress )
datasourcedescription index on ( dsd_prefix, dsd_type_id, dsd_hide )

由于订单是由 dsd_prefix 发出的,但由 eev_prefix 加入,因此使用已经优化索引组件的主要 table 中的 eev_prefix , 让主要 table (不是查找)成为 group/order.

的基础

我还清理了一些查询。更容易为长 table 名称提供别名,因此您可以使用别名来限定查询和相应连接中的每一列。

SELECT STRAIGHT_JOIN
        dsd.dsd_prefix,
        dsd.dsd_partner,
        eev1.eev_dse_element_name,
        devd.devd_explanation,
        devd.devd_min,
        eev1.eev_dev_value,
        devd.devd_max,
        devd.devd_format,
        devd.devd_not_applicable,
        devd.devd_not_available,
        dsd.dsd_nid
    FROM 
        ekohubelementvalue AS eev1
            INNER JOIN devdescription devd
                ON eev1.eev_prefix = devd.devd_prefix
                AND eev1.eev_dse_element_name = devd.devd_element_name
                        
            LEFT JOIN ekohubelementvalue AS eev2
                ON eev1.eev_company_id = eev2.eev_company_id
                AND eev1.eev_prefix = eev2.eev_prefix
                AND eev1.eev_dse_element_name = eev2.eev_dse_element_name
                AND eev1.eev_subcategory = eev2.eev_subcategory
                AND eev1.eev_date_updated < eev2.eev_date_updated

            INNER JOIN datasourcedescription dsd
                ON eev1.eev_prefix = dsd.dsd_prefix
                AND dsd.dsd_type_id != 'MAJ'
                AND dsd.dsd_hide = 'No'

    WHERE 
            eev1.eev_company_id = 'ADD4027'
        AND ( devd.devd_supress IS NULL 
            OR devd.devd_supress <> 'Yes')
        AND eev2.eev_date_updated IS NULL
    GROUP BY 
        eev1.eev_prefix,
        eev1.eev_dse_element_name
    ORDER BY 
        eev1.eev_prefix