0

这是我使用的第一个查询。查询处理时间过长。这将处理表中的数百万行。

select date(datetime), count(*) from LOG l1
where ((datetime >= str_to_date('2013-01-01 00:00:00','%Y-%m-%d %H:%i:%s'))  
and (datetime < str_to_date('2013-01-30 00:00:00','%Y-%m-%d %H:%i:%s'))
and code_subcode in ('8008118', '8008218', '8008318', '8008418'))
and (
select count(*) from log l2
where l2.session_id = l1.session_id and l2.remote_ip = l1.remote_ip and code_subcode
in('8008119', '8008219', '8008319', '8008419')
and TIMEDIFF(l2.datetime, l1.datetime) < 1)
group by date(datetime) order by date(datetime);

经过一番阅读,我发现连接应该比嵌套选择更快,所以我将它转换为这个......

SELECT date(l1.datetime), count(*) from LOG l1
INNER JOIN LOG l2 ON l2.SESSION_ID=l1.SESSION_ID
where ((l1.datetime >= str_to_date('2013-01-01 00:00:00','%Y-%m-%d %H:%i:%s'))
and (l1.datetime < str_to_date('2013-01-30 00:00:00','%Y-%m-%d %H:%i:%s'))
and l1.code_subcode in ('8008118', '8008218', '8008318', '8008418')
and l2.code_subcode in('8008119', '8008219', '8008319', '8008419')
and date(l1.datetime) = date(l2.datetime)
and TIMEDIFF(l2.datetime, l1.datetime) < 1)
GROUP BY date(l1.datetime)
ORDER BY DATE(l1.datetime);

请帮忙,谢谢。


谢谢大家的帮助。事实证明,执行这么长时间的原因是程序在服务器上静默失败。在我的本地环境中执行查询时,它会在 48 秒内处理 800,000 行。如果我有时间,我会研究进一步的优化,现在我有太多的废话要做。

再次感谢!

4

3 回答 3

1

问题是您正在按计算值 ( DATE(l1.datetime)) 进行分组,这意味着 SQL 必须对日志表执行表扫描,并创建临时工作结构来在聚合时保存数据。大概这张桌子很大,所以这真的会伤害你。

如果您经常需要运行此类查询,请考虑DATE(datetime)在 Log 表中添加计算列,然后在其上创建索引。

有关计算列索引的信息,请查看此处

于 2013-10-01T19:46:49.063 回答
1

到目前为止,您收到的所有建议都有其优点...

但不要“猜测”。执行“EXPLAIN”以准确查看 mySQL 认为它应该做什么......这样您就可以弄清楚如何优化您的查询并做得更好。

以下是一些参考资料:

于 2013-10-01T19:54:17.803 回答
0

请尝试运行此查询并告诉它花费了多少时间。此外,我还没有测试查询,只是根据您的联接查询编写了它。请更正语法错误(如果有)。

SELECT date(a.datetime), count(*) from 
(
SELECT datetime,SESSION_ID from LOG where 
(datetime >= str_to_date('2013-01-01 00:00:00','%Y-%m-%d %H:%i:%s')) and 
(datetime < str_to_date('2013-01-30 00:00:00','%Y-%m-%d %H:%i:%s') and
(code_subcode in ('8008118', '8008218', '8008318', '8008418'))
) as a, 
(
SELECT datetime,SESSION_ID from LOG where (code_subcode in('8008119', '8008219', '8008319', '8008419'))
) as b where b.SESSION_ID=a.SESSION_ID and 
date(a.datetime) = date(b.datetime) and TIMEDIFF(b.datetime, a.datetime) < 1)
GROUP BY DATE(a.datetime)
ORDER BY DATE(a.datetime);

另外请使用索引并尝试将日期和时间存储在单独的列中,以最大限度地降低翻译成本。

使用以下代码进行分析

set profiling=1;
//run your query
show profile;

告诉我们输出。谢谢

于 2013-10-01T20:30:31.607 回答