0

我的目标很简单:通过来自不同日志的 IP 地址加入;在客户端,我试图确定 JavaScript 错误是从哪里产生的(例如人类或机器人),我从 if aisset($row[date_xy]) 通过 PHP 推断出来。

这个查询在没有 ORDER BY 的情况下也能正常工作,一旦我把它加入到混合中,MySQL 就会跳到 30% 的 CPU 利用率并在我终止进程之前停留几秒钟。我当然是在本地测试这个。我想使用ORDER BY je.date DESC因为我对最旧的可能条目不感兴趣。

我已经尝试过子选择,我已经有一段时间没有做过比基本 JOIN 更精彩的事情了。重要的是我保持语法 SOL 中性。

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
4

3 回答 3

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);
于 2012-06-28T07:19:22.243 回答
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 ;
于 2012-06-28T08:17:18.823 回答
0

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

于 2012-06-30T09:55:46.807 回答