Tin*_*Tin 6 mysql indexing explain
我是查询优化的新手,所以我承认我还不了解所有内容,但我不明白为什么即使这个简单的查询也没有按预期进行优化。
我的桌子:
+------------------+-----------+------+-----+-------------------+----------------+
| 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 | |
+------------------+-----------+------+-----+-------------------+----------------+
Run Code Online (Sandbox Code Playgroud)
我的索引:
+-----------------+------------+-------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| 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 | | |
+-----------------+------------+-------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
Run Code Online (Sandbox Code Playgroud)
我的查询:
SELECT taskid FROM tasktransitions WHERE transitiondate>'2013-09-31 00:00:00';
Run Code Online (Sandbox Code Playgroud)
给出这个:
+----+-------------+-----------------+------+-------------------+------+---------+------+------+-------------+
| 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 |
+----+-------------+-----------------+------+-------------------+------+---------+------+------+-------------+
Run Code Online (Sandbox Code Playgroud)
如果我正确理解所有内容Using where
,则ALL
意味着所有行都是从存储引擎检索并在服务器层过滤的。这是次优的。为什么它拒绝使用索引而只从存储引擎(innoDB)检索请求的范围?
干杯
Bil*_*win 11
如果 MySQL 估计会选择表的很大一部分,并且它认为在这些情况下表扫描实际上更有效,则它不会使用索引。
打个比方,这就是一本书的索引不包含像“the”这样非常常见的单词的原因——因为在索引中查找单词并找到页码列表是浪费时间。很长的清单,甚至是书中的每一页。简单地从头到尾地阅读这本书会更有效率。
我的经验是,如果查询的搜索条件与表的 20% 以上匹配,MySQL 中就会发生这种情况,这通常是正确的交叉点。根据数据类型、表大小等,可能会有一些变化。
你可以给 MySQL 一个提示,让它相信表扫描的成本会高得令人望而却步,因此它更有可能使用索引。这通常不是必需的,但您可以这样做:
SELECT taskid FROM tasktransitions FORCE INDEX (transitiondate_ix)
WHERE transitiondate>'2013-09-31 00:00:00';
Run Code Online (Sandbox Code Playgroud)