为什么不使用键的最左侧子集来优化此ORDER BY?

轨道轻度竞赛

服务器版本:

[root@cat best]# /usr/libexec/mysqld --version
/usr/libexec/mysqld  Ver 5.1.47 for redhat-linux-gnu on i386 (Source distribution)

架构:

CREATE TABLE `Log` (
    `EntryId` INT UNSIGNED NOT NULL AUTO_INCREMENT,
    `EntryTime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(),
    `Severity` ENUM(
        'LOG_LEVEL_CRITICAL',
        'LOG_LEVEL_ERROR',
        'LOG_LEVEL_WARNING',
        'LOG_LEVEL_NOTICE',
        'LOG_LEVEL_INFO',
        'LOG_LEVEL_DEBUG'
    ) NOT NULL,

    `User` TEXT,
    `Text` TEXT NOT NULL,

    PRIMARY KEY(`EntryId`),
    KEY `TimeId` (`EntryTime`,`EntryId`)
) ENGINE=InnoDB COMMENT="Log of server activity";

询问:

SELECT 
   `EntryId`,
   `EntryTime`, -- or, ideally: UNIX_TIMESTAMP(`EntryTime`) AS `EntryTime_UnixTS`
   `Severity`,
   `User`,
   `Text`
FROM `Log` 
ORDER BY `EntryTime` DESC, `EntryId` DESC
LIMIT 0, 20

根据执行计划(和观察),未使用索引:

id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra
1   SIMPLE       Log    ALL   \N             \N   \N       \N   720   Using filesort

我尝试过几种方法进行重组,但收效甚微,但最重要的是,我想了解这种简单方法为何会失败。我的理解是,任何键的最左侧子集都可用于优化ORDER BY操作。

我的索引不对吗?我可以优化查询吗?

请注意,我也想有条件地添加,例如

WHERE `Severity` <= 'LOG_LEVEL_WARNING'

但是,如果这会使解决方案大为不同,我想先使用基本版本。

转载于MySQL 5.5.32下的SQLFiddle。

耶哈德·卡里亚基(Jehad Keriaki)

原因是索引包含主键。并且由于它是InnoDB,因此默认情况下,所有其他索引中的PK都作为最左侧的字段包含在其中。即在这种情况下的索引是(EntryId,EntryTime,EntryId)。

解决方案是仅在(EntryTime)上具有此索引:

alter table Log drop index TimeId;
alter table Log add index TimeId(EntryTime);
explain SELECT     `EntryId`,    `EntryTime`,     `Severity`,    `User`,    `Text` FROM `Log`  ORDER BY `EntryTime` DESC, `EntryId` DESC LIMIT 0, 20;
+----+-------------+-------+-------+---------------+--------+---------+------+------+-------+
| id | select_type | table | type  | possible_keys | key    | key_len | ref  | rows | Extra |
+----+-------------+-------+-------+---------------+--------+---------+------+------+-------+
|  1 | SIMPLE      | Log   | index | NULL          | TimeId | 4       | NULL |   20 | NULL  |
+----+-------------+-------+-------+---------------+--------+---------+------+------+-------+

高温超导

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么不使用指针数组来优化链接列表,而使用跳过列表呢?

来自分类Dev

为什么不使用查找优化?

来自分类Dev

为什么不使用查找优化?

来自分类Dev

为什么编译器不再使用严格的别名来优化此UB

来自分类Dev

为什么此查询不使用索引?

来自分类Dev

为什么此查询不使用索引?

来自分类Dev

为什么可以使用$来对SpatialPolygonsDataFrame进行子集化?

来自分类Dev

为什么可以使用$来对SpatialPolygonsDataFrame进行子集化?

来自分类Dev

Android Palette:为什么不使用此特定图像?

来自分类Dev

为什么不使用eval扩展此变量?

来自分类Dev

为什么此表格不使用指定的尺寸?

来自分类Dev

为什么不使用此原始sql中的参数?

来自分类Dev

为什么不使用此包含路径变量?

来自分类Dev

为什么这个类的方法的实例不使用此参数?

来自分类Dev

为什么不使用此JavaScript代码覆盖数组元素?

来自分类Dev

Ocaml 模式匹配:为什么不使用此匹配?

来自分类Dev

为什么不使用内容协商来返回JSON对象?

来自分类Dev

人们为什么不使用序号来存储图像?

来自分类Dev

mysql为什么不使用键进行简单选择?

来自分类Dev

MySQL:为什么不使用索引的所有键?

来自分类Dev

mysql为什么不使用键进行简单选择?

来自分类Dev

为什么CMS数据库不使用外键?

来自分类Dev

为什么不使用std :: memory_order_acq_rel

来自分类Dev

Clang为什么要优化此代码?

来自分类Dev

为什么此填充不使内容居中?

来自分类Dev

为什么优化器不使用我唯一的过滤索引?

来自分类Dev

我还能做些什么来优化此查询?

来自分类Dev

为什么在C ++ 17上不能使用`{}`而不使用`()`构造此派生类?

来自分类Dev

初学者的问题-为什么C使用*来声明指针而不使用&?

Related 相关文章

  1. 1

    为什么不使用指针数组来优化链接列表,而使用跳过列表呢?

  2. 2

    为什么不使用查找优化?

  3. 3

    为什么不使用查找优化?

  4. 4

    为什么编译器不再使用严格的别名来优化此UB

  5. 5

    为什么此查询不使用索引?

  6. 6

    为什么此查询不使用索引?

  7. 7

    为什么可以使用$来对SpatialPolygonsDataFrame进行子集化?

  8. 8

    为什么可以使用$来对SpatialPolygonsDataFrame进行子集化?

  9. 9

    Android Palette:为什么不使用此特定图像?

  10. 10

    为什么不使用eval扩展此变量?

  11. 11

    为什么此表格不使用指定的尺寸?

  12. 12

    为什么不使用此原始sql中的参数?

  13. 13

    为什么不使用此包含路径变量?

  14. 14

    为什么这个类的方法的实例不使用此参数?

  15. 15

    为什么不使用此JavaScript代码覆盖数组元素?

  16. 16

    Ocaml 模式匹配:为什么不使用此匹配?

  17. 17

    为什么不使用内容协商来返回JSON对象?

  18. 18

    人们为什么不使用序号来存储图像?

  19. 19

    mysql为什么不使用键进行简单选择?

  20. 20

    MySQL:为什么不使用索引的所有键?

  21. 21

    mysql为什么不使用键进行简单选择?

  22. 22

    为什么CMS数据库不使用外键?

  23. 23

    为什么不使用std :: memory_order_acq_rel

  24. 24

    Clang为什么要优化此代码?

  25. 25

    为什么此填充不使内容居中?

  26. 26

    为什么优化器不使用我唯一的过滤索引?

  27. 27

    我还能做些什么来优化此查询?

  28. 28

    为什么在C ++ 17上不能使用`{}`而不使用`()`构造此派生类?

  29. 29

    初学者的问题-为什么C使用*来声明指针而不使用&?

热门标签

归档