我有一张表(日志),大约有100k行。每行都有一个与创建时间关联的时间戳。当我按这个时间戳排序时,即使有很多WHERE标准,查询也比没有排序要慢得多。我似乎无法找到加快速度的方法。我尝试了各种索引。
查询返回大约25k行。我有类似的查询需要运行,WHERE标准略有不同。
使用ORDER BY,查询需要0.6秒。如果没有ORDER BY,则查询需要0.003秒。
表结构如下。
CREATE TABLE IF NOT EXISTS `logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`shipment_id` int(11) DEFAULT NULL,
`time` timestamp NULL DEFAULT NULL,
`initials` varchar(50) DEFAULT NULL,
`result` int(11) DEFAULT NULL,
`information` int(11) DEFAULT NULL,
`issues` varchar(5) DEFAULT NULL,
`fw_actions` varchar(999) DEFAULT NULL,
`noncompliant` tinyint(4) DEFAULT NULL,
`noncompliant_lead_initials` varchar(50) DEFAULT NULL,
`noncompliant_lead_time` varchar(20) DEFAULT NULL,
`event_id` int(11) DEFAULT NULL,
`action_id` int(11) DEFAULT NULL,
`resolution_id` int(11) DEFAULT NULL,
`noncompliant_reviewed` tinyint(4) NOT NULL DEFAULT '0',
`violation` tinyint(4) DEFAULT NULL,
`approved` tinyint(4) NOT NULL DEFAULT '0',
`approved_time` timestamp NULL DEFAULT NULL,
`approver` int(11) DEFAULT NULL,
`reviewed` tinyint(4) NOT NULL DEFAULT '0',
`reviewed_time` timestamp NULL DEFAULT NULL,
`reviewer` int(11) DEFAULT NULL,
`editor` int(11) DEFAULT NULL,
`summary` varchar(999) DEFAULT NULL,
`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `LOGS_SHIPMENT_ID_TIME` (`shipment_id`,`time`,`action_id`),
KEY `SHIPMENT_ID_IDX` (`shipment_id`),
KEY `logs_updated_index` (`updated`),
KEY `violation_idx` (`violation`,`approved`,`reviewed`,`shipment_id`,`time`,`reviewer`,`approver`,`editor`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=100022 ;
查询
SELECT * FROM logs
WHERE (logs.approved != 1) AND (logs.violation = 1)
ORDER BY logs.`time` DESC
我的EXPLAIN看起来像这样
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE logs ref violation_idx violation_idx 2 const 1000 Using index condition; Using where; Using filesort
任何人都有诀窍吗?谢谢!
答案 0 :(得分:1)
key_len列说MySQL只使用索引的2个字节" violation_idx"。所以它只使用前两列,"违反"和"批准",每个都是tinyint(一个字节)。
您可能能够通过制作" time"来提高此查询的效果这个索引中的第三列。目前,它是第五列。我不知道你还在做什么其他的询问;这种变化可能会影响其他查询的性能。
此外,您可能可以通过在" time"上创建额外的索引来提高性能。单独的列。这些都值得测试。
大多数dbms都会受益于一个索引,该索引在" time"上有降序排序,但MySQL won't。
index_col_name规范可以以ASC或DESC结尾。这些 允许使用关键字以用于指定升序的未来扩展 或降序索引值存储。目前,他们被解析但是 忽略;索引值始终按升序存储。
你必须找到自己的舒适程度。今天,创建一个索引" DESC"清楚地表达了您的意图,但是未来升级到MySQL会开始解析并实现该表达式,这可能会损害其他查询的性能。
答案 1 :(得分:0)
及时创建索引。进一步的索引可以帮助您在时间索引的方向上添加额外的过滤器。