如何在按另一列排序时按一列过滤?

时间:2014-11-12 10:09:25

标签: mysql query-optimization innodb

架构:

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 `EntryTime` (`EntryTime`)
) ENGINE=InnoDB COMMENT="Log of server activity";

查询:

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

根据观察和执行计划(虽然这需要FORCE INDEX小数据集!),索引正在按需使用:

id  select_type  table  type  possible_keys  key        key_len  ref  rows  Extra
1   SIMPLE       Log    index \N             EntryTime  4        \N   20    

现在我想添加一个范围条件:

WHERE `Severity` <= 'LOG_LEVEL_WARNING'

但是我无法弄清楚如何选择一个密钥,这样这个简单的查询仍然可以使用索引,同时对一列进行排序并对另一列进行过滤。我越是想到这一点,我的弱直觉表明它在当前形式下查询甚至不可能,尤其是因为条件在范围

你会怎么做?

1 个答案:

答案 0 :(得分:1)

在我看来,你需要创建一个包含三个必填字段的索引:

CREATE INDEX test_idx
          ON Log (Severity,EntryTime,EntryId);

Ther服务器将能够使用此索引,因为它包含执行查询所需的所有内容。