我想知道索引是否会加快此查询速度。我上次检查时需要9秒。流量表有大约300k行,列表和用户5k行。如果这只是一个糟糕的查询,我也会受到嘲笑/羞辱。我很久以前写过它。
它应该获得具有最多页面浏览量(流量)的列表。如果缺乏解释,请告诉我。
SELECT traffic_listingid AS listing_id,
COUNT(traffic_listingid) AS genuine_hits,
COUNT(DISTINCT traffic_ipaddress) AS distinct_ips,
users.username,
listings.listing_address,
listings.datetime_created,
DATEDIFF(NOW(), listings.datetime_created) AS listing_age_days
FROM traffic
LEFT JOIN listings
ON traffic.traffic_listingid = listings.listing_id
LEFT JOIN users
ON users.id = listings.seller_id
WHERE traffic_genuine = 1
AND listing_id IS NOT NULL
AND username IS NOT NULL
AND DATEDIFF(NOW(), traffic_timestamp) < 24
GROUP BY traffic_listingid
ORDER BY distinct_ips DESC
LIMIT 10
P.S。
ENGINE=MyISAM /
MySQL Server 4.3
答案 0 :(得分:3)
图片的标题说明:
1.你有
LEFT JOIN listings
ON traffic.traffic_listingid = listings.listing_id
...
WHERE ...
AND listing_id IS NOT NULL
此条件取消LEFT JOIN
。将您的查询更改为:
INNER JOIN listings
ON traffic.traffic_listingid = listings.listing_id
并从listing_id IS NOT NULL
条件中移除WHERE
。
同样的事情也适用于LEFT JOIN user
和username IS NOT NULL
。
2.检查traffic_timestamp
:
DATEDIFF(NOW(), traffic_timestamp) < 24
使索引难以使用。将其更改为可以使用索引的类似内容 (并检查我的版本相同,我可能有错误):
traffic_timestamp >= CURRENT_DATE() - INTERVAL 23 DAY
3. COUNT(non-nullable-column)
相当于COUNT(*)
。改变:
COUNT(traffic_listingid) AS genuine_hits,
为:
COUNT(*) AS genuine_hits,
因为它在MySQL中有点快(虽然我不确定版本4.3)
对于索引问题,您应该在每个用于加入的列上至少有一个索引。为traffic_timestamp
添加一个也可能会有所帮助。
如果您告诉我们traffic_ipaddress
和traffic_timestamp
在哪些表格中,以及EXPLAIN EXTENDED
显示的内容,可能会有更好的想法。
再次阅读查询,它似乎仅在表GROUP BY
中为traffic
,而其他2个表用于获取参考数据。因此,查询等同于(traffic group by)-join-listing-join-user。不确定这对你的MySQL旧版本是否有帮助,但如果一个查询在你的系统中运行得更快,那么拥有查询和测试的两个版本可能会很好。
答案 1 :(得分:0)
索引应始终放在您在where子句中使用的列上。
在这种情况下,listingid看起来是一个不错的选择,以及users.id,seller_id和traffic_timestamp。
在查询前使用EXPLAIN EXTENDED
查看MySQL建议您使用的内容(显示触摸的行数以及使用的索引)