为什么不使用一个关键的最左边的子集来优化这个ORDER BY?(Why is the leftmos

2019-10-21 06:34发布

服务器版本:

[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的32年5月5日在重现了SQLFiddle。

Answer 1:

原因是,你的索引包括在它的主键。 并且由于它是InnoDB的,默认情况下PK是在所有其他指标作为最左边的字段ancluded。 即,在这种情况下,该索引是(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  |
+----+-------------+-------+-------+---------------+--------+---------+------+------+-------+

HTH



文章来源: Why is the leftmost subset of a key not being used to optimise this ORDER BY?