5

我是查询优化的新手,所以我接受我还不了解所有内容,但我不明白为什么即使是这个简单的查询也没有按预期进行优化。

我的桌子:

+------------------+-----------+------+-----+-------------------+----------------+
| Field            | Type      | Null | Key | Default           | Extra          |
+------------------+-----------+------+-----+-------------------+----------------+
| tasktransitionid | int(11)   | NO   | PRI | NULL              | auto_increment |
| taskid           | int(11)   | NO   | MUL | NULL              |                |
| transitiondate   | timestamp | NO   | MUL | CURRENT_TIMESTAMP |                |
+------------------+-----------+------+-----+-------------------+----------------+

我的索引:

+-----------------+------------+-------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table           | Non_unique | Key_name          | Seq_in_index | Column_name      | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------+------------+-------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tasktransitions |          0 | PRIMARY           |            1 | tasktransitionid | A         |         952 |     NULL | NULL   |      | BTREE      |         |               |
| tasktransitions |          1 | transitiondate_ix |            1 | transitiondate   | A         |         952 |     NULL | NULL   |      | BTREE      |         |               |
+-----------------+------------+-------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

我的查询:

SELECT taskid FROM tasktransitions WHERE transitiondate>'2013-09-31 00:00:00';

给出了这个:

+----+-------------+-----------------+------+-------------------+------+---------+------+------+-------------+
| id | select_type | table           | type | possible_keys     | key  | key_len | ref  | rows | Extra       |
+----+-------------+-----------------+------+-------------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | tasktransitions | ALL  | transitiondate_ix | NULL | NULL    | NULL | 1082 | Using where |
+----+-------------+-----------------+------+-------------------+------+---------+------+------+-------------+

如果我正确理解了所有内容Using whereALL则意味着所有行都从存储引擎中检索并在服务器层进行过滤。这是次优的。为什么它拒绝使用索引,只从存储引擎(innoDB)中检索请求的范围?

干杯

4

4 回答 4

7

如果 MySQL 估计它会选择表的很大一部分,它就不会使用索引,并且它认为在这些情况下表扫描实际上更有效。

以此类推,这就是一本书的索引不包含像“the”这样非常常见的词的原因——因为在索引中查找这个词并发现页码列表是一个很长的清单,甚至是书中的每一页。简单地阅读书的封面会更有效。

我的经验是,如果查询的搜索条件匹配大于 20% 的表,这在 MySQL 中会发生,这通常是正确的交叉点。根据数据类型、表大小等可能会有一些变化。

你可以给 MySQL 一个提示,让它相信表扫描会非常昂贵,因此它更有可能使用索引。这通常不是必需的,但您可以这样做:

SELECT taskid FROM tasktransitions FORCE INDEX (transitiondate_ix)
WHERE transitiondate>'2013-09-31 00:00:00';
于 2013-11-04T17:55:16.337 回答
0

以防万一,它可以帮助某人。

我有一个带有 varchar 列 _id 的表(long int 编码为字符串)。我为该列添加了索引,但查询仍然很慢。我正在执行这个查询:

select * from table where (_id = 2221835089) limit 1

我意识到 _id 列不是作为字符串生成的(我是 Laravel 作为 DB 框架)。好吧,如果在 where 子句中使用正确的数据类型执行查询,那么一切都会像魅力一样:

select * from table where (_id = '2221835089') limit 1

于 2020-10-15T07:12:29.347 回答
0

我是 MySQL 8.0 的新手,已经完成了 2 个简单的教程,只有两个主题对我没有用,其中之一是索引。我阅读了标有“2 个答案”的部分,发现使用该部分末尾建议的陈述似乎违背了原件USE INDEXFORCE INDEX下面陈述的目的。建议的语句就像通过WHERE语句而不是 MySQL 使用USE INDEXor来对表进行排序FORCE INDEX。它有效,但在我看来它与使用自然USE INDEXor不同FORCE INDEX。有谁知道为什么 MySQL 忽略了我在 Lname 列上索引 10 行表的简单请求?

场地 类型 无效的 钥匙 默认 额外的
ID 整数 PRI 无效的 自动递增
名称 varchar(20) 穆尔 无效的
名称 varchar(20) 穆尔 无效的
城市 varchar(15) 无效的
出生日期 日期 无效的
CREATE INDEX idx_Lname ON TestTable (Lname);
SELECT * FROM TestTable USE INDEX (idx_Lname);
SELECT * From Testtable FORCE INDEX (idx_LastFirst); 
于 2021-04-01T13:54:39.423 回答
0

I once was trying to join two tables and MySQL was refusing to use an index, resulting in >500ms queries, sometimes a few seconds. Turns out the column I was joining on had different encodings on each table. Changing both to the same encoding sped up the query to consistently less than 100ms.

于 2022-02-21T19:40:38.603 回答