我有以下MySQL查询,在linux VM上大约需要40秒:
SELECT
* FROM `clients_event_log`
WHERE
`ex_long` = 1475461 AND
`type` in (2, 1) AND NOT
(
(category=1 AND error=-2147212542) OR
(category=7 AND error=67)
)
ORDER BY `ev_time` DESC LIMIT 100
该表有大约700万行,aprox。 800 MB大小,并且在WHERE和ORDER BY子句中使用的所有字段都有索引。
现在,如果我以一种在外部SELECT中完成排序的方式更改查询,那么一切都运行得更快(大约100ms):
SELECT res.* FROM
(
SELECT * FROM `clients_event_log`
WHERE
`ex_long` = 1475461 AND
`type` in (2, 1) AND NOT
(
(category=1 AND error=-2147212542) OR
(category=7 AND error=67)
)
) AS res
ORDER BY res.ev_time DESC LIMIT 0, 100
你知道为什么第一个查询花了这么长时间吗?谢谢。
稍后更新:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE clients_event_log index category,ex_long,type,error,categ_error ev_time 4 NULL 5636 Using where
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
2 DERIVED clients_event_log ref category,ex_long,type,error,categ_error ex_long 5 131264 Using where
表格定义:
CREATE TABLE `clients_event_log` (
`ev_id` int(11) NOT NULL,
`type` int(6) NOT NULL,
`ev_time` int(11) NOT NULL,
`category` smallint(6) NOT NULL,
`error` int(11) NOT NULL,
`ev_text` varchar(1024) DEFAULT NULL,
`userid` varchar(20) DEFAULT NULL,
`ex_long` int(11) DEFAULT NULL,
`client_ex_long` int(11) DEFAULT NULL,
`ex_text` varchar(1024) DEFAULT NULL,
PRIMARY KEY (`ev_id`),
KEY `category` (`category`),
KEY `ex_long` (`ex_long`),
KEY `type` (`type`),
KEY `ev_time` (`ev_time`),
KEY `error` (`error`),
KEY `categ_error` (`category`,`error`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
答案 0 :(得分:0)
我最终使用了第二个查询(内部SELECT),因为MySQL优化器决定总是使用ev_time
索引,即使我尝试了包含WHERE和ORDER BY子句中的列的多个版本的复合索引。
使用force index (ex_long)
也有效。
MySQL版本 5.5.38
谢谢。
答案 1 :(得分:0)
添加这些
INDEX(ev_long, ev_time),
INDEX(ev_long, type)
并使用查询的第一种格式,让优化器根据统计数据决定哪种更好。
答案 2 :(得分:0)
SELECT provider.* FROM user,person,provider,meta_data_specialisation
where user.person_id = person.id and user.id = provider.user_id and
provider.specialization_id = meta_data_specialisation.id and
( user.mobile like '%+9143%')
order by provider.created_date_and_time desc limit 0 , 10;
请问有人可以优化此查询,因为它花费了太多时间,如果我取消订单,它会在几秒钟内执行。