MySQL:IP地址JOIN + ORDER DESC会降低性能

时间:2012-06-28 07:13:32

标签: mysql

我的目标很简单:通过不同日志的IP地址加入;在客户端,我正在尝试确定从错误产生的JavaScript错误(例如人类或机器人),我通过PHP确定了isset($ row [date_xy])。

这个查询在没有ORDER BY的情况下工作正常,一旦我把它扔进混合MySQL跳转到30%CPU利用率并在我杀死进程之前停留几秒钟。我当然在本地进行测试。我想使用 ORDER BY je.date DESC ,因为我对最老的条目不感兴趣。

我尝试过子选择,已经有一段时间了,因为我做了比基本JOIN更好的事情。保持SOL-neutral语法非常重要。

SELECT 
je.date AS date_js, 
lb.date AS date_lb, 
lh.date AS date_lh 

FROM log_javascript_errors AS je 

LEFT JOIN log_bots AS lb ON je.ip = lb.ip 

LEFT JOIN log_humans AS lh ON je.ip = lh.ip 

ORDER BY je.date DESC 

LIMIT 20, 20

3 个答案:

答案 0 :(得分:2)

您必须为log_javascript_errors.date添加索引才能加快排序速度。 并使用log_bots.ip,log_humans.ip,log_javascript_errors.ip的索引来加快连接速度。

更新

CREATE INDEX je_date ON log_javascript_errors (date);
CREATE INDEX je_ip ON log_javascript_errors (ip);
CREATE INDEX lb_ip ON log_bots (ip);
CREATE INDEX lh_ip ON log_humans (ip);

答案 1 :(得分:1)

添加适当的索引后,如果查询仍然很慢,您可以尝试以下变体:

SELECT 
je.date AS date_js, 
lb.date AS date_lb, 
lh.date AS date_lh 

FROM 
    ( SELECT ip, date 
      FROM log_javascript_errors 
      ORDER BY date DESC
      LIMIT 40
    ) AS je 

LEFT JOIN log_bots AS lb ON je.ip = lb.ip 

LEFT JOIN log_humans AS lh ON je.ip = lh.ip 

ORDER BY je.date DESC 

LIMIT 20, 20 ;

答案 2 :(得分:0)

我已经走了一条不同的路线,因为我必须承认,当我最初创建这些表时,表的设计并未考虑这种可能性。我们都遇到过这个。我确实学习了SQL供应商中立的CASE语法,但是虽然发现我甚至不需要在经过一些修改后使用它,所以我对我收到的两个回复进行了投票,感谢我扩展了对SQL的理解。对于那些发现这个问题与他们的目标直接相关的人,我最后添加了一个“类型”列,我使用服务器脚本语言来填充其余部分,以便生成我需要在日志中看到的内容。我想如果我从头开始重新设计它,我会为所有“类型”(人类,搜索引擎和拒绝)创建一个主会话表,然后可能尝试双LEFT JOIN,虽然我不确定它会有多好用。