【发布时间】:2012-12-23 21:04:25
【问题描述】:
使用左连接的 mysql 查询非常慢时遇到问题。
SELECT ip,T1.ipaddr,host,referrer,agent,page,url,thedate,DV,PV,notes
FROM visits_temp AS T1
LEFT JOIN (
SELECT ipaddr,COUNT(DISTINCT LEFT(thedate,10)) AS DV
FROM visits GROUP BY ipaddr
) AS T2 ON T1.ipaddr = T2.ipaddr
LEFT JOIN (
SELECT ipaddr,notes
FROM topvisitors
) As T3 ON T3.ipaddr = T1.ipaddr
LEFT JOIN (
SELECT ipaddr,COUNT(ip) AS PV
FROM visits
GROUP BY ipaddr
) AS T4 ON T4.ipaddr = T1.ipaddr
WHERE referrer = '' AND
thedate BETWEEN '2013-01-07 00:00:00' AND '2013-01-09 23:59:59'
GROUP BY T1.ip
ORDER BY thedate desc
这里的目标是获取网站的所有直接访问者流量,而不是 LEFT JOINS 进行查找以提供访问的总天数 (DV) 和查看的总页面数 (PV)。访问表目前有大约 290 万条记录,并且 ipaddr 和 thedate 字段已被索引。此查询需要近 90 秒才能完成。
SELECT ipaddr,COUNT(DISTINCT LEFT(thedate,10)) AS DV FROM visits GROUP BY ipaddr
或
SELECT ipaddr,COUNT(ip) AS PV FROM visits GROUP BY ipaddr
LEFT JOINS 中的各个 select 语句在自行运行时将在 0.03 秒内完成。在这种情况下,也许 LEFT JOIN 不是正确的方法,我愿意接受替代方案。
【问题讨论】:
-
你试过
EXPLAIN PLAN吗?它显示了什么? -
在日期范围内使用
between时,我的大型表的性能非常糟糕。当使用这种结构时,mysql 会以某种方式拒绝索引。 -
@MarcB 使用
Date >= LowerBownd and Date <=UpperBound能解决问题吗? -
不。无论如何,就编译器/解析器而言,
x between y and z与x >=y and x<=z相同。永远无法找到解决方法,最后只是对表进行了下注和分区。 -
ipaddr 和 thedate 字段的数据类型是什么?
标签: mysql performance optimization left-join