【发布时间】:2014-11-12 10:09:25
【问题描述】:
架构:
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'
但我不知道如何选择一个键,这样这个简单的查询仍然可以使用索引,同时对一个列进行排序并在另一列上进行过滤。我想得越多,我的弱 SQL 直觉就越表明它甚至不可能使用当前形式的查询,尤其是因为条件在 范围 上。
你会如何处理这个问题?
【问题讨论】:
-
在
Severity,EntryTime,EntryId上创建一个新索引怎么样? -
@juergend:
WHERE会很慢,不是吗?您的新严重性指数未被使用 -
@OscarPérez:嗯,这似乎行得通。我不知道怎么做,尤其是因为我在this answer!
标签: mysql query-optimization innodb