2011-09-30 57 views
3

我想知道索引是否会加快这个查询。上次检查时需要9秒。交通表有大约300k行,列表和用户5k行。如果这只是一个蹩脚的问题,我也会嘲笑/羞辱。我很久以前写过。我应该为这个臃肿的查询添加什么SQL索引?

它应该得到最多的页面浏览量(流量)。让我知道如果解释缺乏。

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

如果你提供了每列中的表格,这将有所帮助。再加上表格定义和'EXPLAIN SELECT ...'显示的内容。 –

+1

4.3?好家伙!你可以升级或更换提供商,你知道:) –

回答

3

图片的标题说明:

1.You有

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 

,并从WHERE条件删除listing_id IS NOT NULL

同样的事情适用于LEFT JOIN userusername 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_ipaddresstraffic_timestamp是什么,以及EXPLAIN EXTENDED显示什么,有人可能有更好的主意。

再次读取查询,它似乎只是traffic中的GROUP BY,其他2个表格用于获取参考数据。所以,查询相当于一个(流量组by)-join-listing-join-user。不知道这是否有助于您的MySQL旧版本,但如果在您的系统中运行更快的查询,那么同时使用这两个版本的查询并进行测试可能会很好。

+0

感谢您花时间解释这一点。 traffic_ *是流量表的一部分。我目前只在traffic_listingid列有一个索引,但我会尝试这些建议。 –

+0

如果它是'PRIMARY KEY',你可能在'users.id'上也有一个。 –

0

索引应始终放在where子句中使用的列上。

在这种情况下,listingid看起来像一个很好的选项,以及users.id,seller_id和traffic_timestamp。

使用EXPLAIN EXTENDED在查询前看到什么MySQL的建议你(它显示行有多少感动,它所使用的索引)

相关问题