查询优化器不使用索引

时间:2017-04-17 00:43:48

标签: mysql performance indexing

我有两个表CUSTOMER_ORDER_PUBLIC和LINEITEM_PUBLIC,它们具有以下索引:

+-----------------------+------------+---------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table                 | Non_unique | Key_name      | Seq_in_index | Column_name   | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------------+------------+---------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| CUSTOMER_ORDER_PUBLIC |          1 | O_ORDERKEY    |            1 | O_ORDERKEY    | A         |     2633457 |     NULL | NULL   | YES  | BTREE      |         |               |
| CUSTOMER_ORDER_PUBLIC |          1 | O_ORDERDATE   |            1 | O_ORDERDATE   | A         |        2350 |     NULL | NULL   | YES  | BTREE      |         |               |
| CUSTOMER_ORDER_PUBLIC |          1 | PUB_C_CUSTKEY |            1 | PUB_C_CUSTKEY | A         |      273000 |     NULL | NULL   |      | BTREE      |         |               |
+-----------------------+------------+---------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

+-----------------+------------+----------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table           | Non_unique | Key_name             | Seq_in_index | Column_name      | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------+------------+----------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| LINEITEM_PUBLIC |          0 | PRIMARY              |            1 | PUB_L_ORDERKEY   | A         |    16488602 |     NULL | NULL   |      | BTREE      |         |               |
| LINEITEM_PUBLIC |          0 | PRIMARY              |            2 | PUB_L_LINENUMBER | A         |    44146904 |     NULL | NULL   |      | BTREE      |         |               |
| LINEITEM_PUBLIC |          1 | LINEITEM_PRIVATE_FK2 |            1 | PUB_L_PARTKEY    | A         |     2083757 |     NULL | NULL   |      | BTREE      |         |               |
| LINEITEM_PUBLIC |          1 | LINEITEM_PRIVATE_FK3 |            1 | PUB_L_SUPPKEY    | A         |       85599 |     NULL | NULL   |      | BTREE      |         |               |
+-----------------+------------+----------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

每次我运行特定查询的解释时,我都会得到以下结果:

mysql> EXPLAIN SELECT *
    FROM CUSTOMER_ORDER_PUBLIC
    LEFT OUTER JOIN LINEITEM_PUBLIC  ON O_ORDERKEY= PUB_L_ORDERKEY;
+----+-------------+-----------------------+------------+------+---------------+---------+---------+---------------------------------------+---------+----------+-------+
| id | select_type | table                 | partitions | type | possible_keys | key     | key_len | ref                                   | rows    | filtered | Extra |
+----+-------------+-----------------------+------------+------+---------------+---------+---------+---------------------------------------+---------+----------+-------+
|  1 | SIMPLE      | CUSTOMER_ORDER_PUBLIC | NULL       | ALL  | NULL          | NULL    | NULL    | NULL                                  | 2900769 |   100.00 | NULL  |
|  1 | SIMPLE      | LINEITEM_PUBLIC       | NULL       | ref  | PRIMARY       | PRIMARY | 4       | TPCH.CUSTOMER_ORDER_PUBLIC.O_ORDERKEY |       2 |   100.00 | NULL  |
+----+-------------+-----------------------+------------+------+---------------+---------+---------+---------------------------------------+---------+----------+-------+

由于某种原因,即使我使用FORCE INDEX,查询优化器也没有使用索引(O_ORDERKEY)。我知道很多人发布了类似的问题,但我尝试了一切,似乎没有任何帮助!

非常感谢任何其他建议!

修改  使用的查询如下:

SELECT * FROM CUSTOMER_ORDER_PUBLIC
    LEFT OUTER JOIN LINEITEM_PUBLIC  ON O_ORDERKEY= PUB_L_ORDERKEY;

2 个答案:

答案 0 :(得分:2)

对于此查询:

Telegram

对于此查询,您需要module SpecialShortcut def foo # ... end end # config/initializers/telegram_extensions.rb Telegram.extend(SpecialShortcut) 上的索引。当然,您已经拥有此索引,因为这是主键中的第一个键。

没有理由在SELECT * FROM CUSTOMER_ORDER_PUBLIC cop LEFT OUTER JOIN LINEITEM_PUBLIC lp ON cop.O_ORDERKEY = lp.PUB_L_ORDERKEY; 上使用索引,因为表中的所有行都将转到结果集。

答案 1 :(得分:1)

GROUP BY提示告诉优化器对表的完整扫描非常昂贵。

观察到的行为最可能的解释是优化器认为它需要访问表中的每一行,并且提示中建议的索引是查询的覆盖索引。 / p>

根据EXPLAIN输出,我们只能看到JOIN操作中单个谓词的证据。看起来优化器正在选择FORCE INDEX作为连接的驱动表,并使用CUSTOMER_ORDER_PUBLIC表上的索引。

我不确定是否有任何问题可以解答您提出的问题。 (我不确定是否有问题。)如果没有实际的SQL语句,我们只是在猜测。

我有一个问题:除了LINEITEM_PUBLIC提示之外,为什么我们期望优化器使用特定索引?为什么这是一个合理的期望?