Tom*_*Tom 22 mysql optimization
我真的很难让查询时间缩短,它目前不得不查询250万行,并且需要超过20秒
这是查询
SELECT play_date AS date, COUNT(DISTINCT(email)) AS count
FROM log
WHERE play_date BETWEEN '2009-02-23' AND '2020-01-01'
AND type = 'play'
GROUP BY play_date
ORDER BY play_date desc;
`id` int(11) NOT NULL auto_increment,
`instance` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`type` enum('play','claim','friend','email') NOT NULL,
`result` enum('win','win-small','lose','none') NOT NULL,
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
`play_date` date NOT NULL,
`email_refer` varchar(255) NOT NULL,
`remote_addr` varchar(15) NOT NULL,
PRIMARY KEY (`id`),
KEY `email` (`email`),
KEY `result` (`result`),
KEY `timestamp` (`timestamp`),
KEY `email_refer` (`email_refer`),
KEY `type_2` (`type`,`timestamp`),
KEY `type_4` (`type`,`play_date`),
KEY `type_result` (`type`,`play_date`,`result`)
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE log ref type_2,type_4,type_result type_4 1 const 270404 Using where
Run Code Online (Sandbox Code Playgroud)
该查询使用type_4索引.
有谁知道我怎么能加快这个查询速度?
谢谢汤姆
Hen*_*ing 18
这已经相对不错了.性能接收器是查询必须比较270404 varchars的相等性COUNT(DISTINCT(email)),这意味着必须读取270404行.
您可以通过创建覆盖索引来加快计数.这意味着不需要读取实际行,因为索引本身中存在所有必需的信息.
为此,请按如下所示更改索引:
KEY `type_4` (`type`,`play_date`, `email`)
Run Code Online (Sandbox Code Playgroud)
如果不能加快速度,我会感到惊讶.
(感谢MarkR的正确任期.)
你的索引可能和你能得到的一样好.您在where子句中的2列上有一个复合索引,并且explain您发布的表明它正在使用.不幸的是,有270,404行符合您的where条款中的标准,所有这些都需要考虑.此外,您不会在select列表中返回不必要的行.
我的建议是每天(或每小时或任何有意义的)聚合数据并缓存结果.这样您就可以立即访问稍微陈旧的数据.希望这对您的目的是可以接受的.
| 归档时间: |
|
| 查看次数: |
9973 次 |
| 最近记录: |