架构:
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'
但是我无法弄清楚如何选择一个密钥,这样这个简单的查询仍然可以使用索引,同时对一列进行排序并对另一列进行过滤。我越是想到这一点,我的弱直觉表明它在当前形式下查询甚至不可能,尤其是因为条件在范围。
你会怎么做?
答案 0 :(得分:1)
在我看来,你需要创建一个包含三个必填字段的索引:
CREATE INDEX test_idx
ON Log (Severity,EntryTime,EntryId);
Ther服务器将能够使用此索引,因为它包含执行查询所需的所有内容。