sql 带有子查询优化的查询

sql query with subqueries optimization

我是 SQL 的初学者,我在使用下面的子查询时遇到问题。我设置子查询的原因是我需要以不同于数据在主 table 上排序的方式对列进行排序和分组。还有其他方法可以优化此查询吗?一直超时,已经运行超过30分钟了。我想尽可能避免重新扫描 piwik_log_visit table。有没有办法只按特定列排序或分组?我感谢任何帮助。谢谢!

Set @theDate = cast('2015-11-26 08:00:00' as datetime);

SELECT  t2.idorder AS 'Order ID',
        (
            SELECT  COALESCE(NULLIF(t3.referer_name,''), 'Direct')
            FROM    piwik_log_visit t3
            WHERE   conv(hex(t3.idvisitor), 16, 10) = conv(hex(t2.idvisitor), 16, 10) 
            AND     t3.visit_first_action_time >= (@theDate - INTERVAL 32 DAY)
            ORDER BY t3.visit_last_action_time DESC
            limit 1
        ) AS 'Referrer (Last)',
        (
            SELECT  COALESCE(NULLIF(t4.referer_name,''), 'Direct')
            FROM    piwik_log_visit t4
            WHERE   inet_ntoa(conv(hex(t4.location_ip), 16, 10)) = inet_ntoa(conv(hex(t1.location_ip), 16, 10)) 
            AND     t4.visit_first_action_time >= (@theDate - INTERVAL 32 DAY)
            GROUP BY inet_ntoa(conv(hex(t4.location_ip), 16, 10))
            ORDER BY t4.visit_first_action_time
            limit 1
        ) AS 'Referrer (IP:First)',
        t1.referer_url AS 'Referrer URL'
FROM    piwik_log_visit t1, 
        piwik_log_conversion t2
WHERE   conv(hex(t1.idvisitor), 16, 10) = conv(hex(t2.idvisitor), 16, 10) 
AND     t2.idorder IS NOT NULL 
AND     t2.server_time BETWEEN '2015-11-25 07:59:59' AND '2015-11-26 08:00:00' 
AND     t1.visit_first_action_time >= (@theDate - INTERVAL 32 DAY)
GROUP BY t2.idorder

解释计划:

http://screencast.com/t/3loUAUkTe

性能不佳的主要原因是表之间的连接条件。由于涉及的列上的数据转换,它们无法使用索引进行优化。如果没有索引,连接将成为笛​​卡尔连接,然后通过计算连接表达式来过滤。

为什么需要在 t1.idvisitor 和 t2.idvisitor 上进行转换?将连接条件更改为简单的

WHERE t1.idvisitor = t2.idvisitor

会有很大帮助。与 t3 和 t4 相同。

尝试不使用 conv(hex(), ,).

Set @theDate = cast('2015-11-26 08:00:00' as datetime); SELECT t2.idorder AS 'Order ID', ( SELECT COALESCE(NULLIF(t3.referer_name,''), 'Direct') FROM piwik_log_visit t3 WHERE t3.idvisitor = t2.idvisitor AND t3.visit_first_action_time >= (@theDate - INTERVAL 32 DAY) ORDER BY t3.visit_last_action_time DESC limit 1 ) AS 'Referrer (Last)', ( SELECT COALESCE(NULLIF(t4.referer_name,''), 'Direct') FROM piwik_log_visit t4 WHERE t4.location_ip = t1.location_ip AND t4.visit_first_action_time >= (@theDate - INTERVAL 32 DAY) GROUP BY t4.location_ip ORDER BY t4.visit_first_action_time limit 1 ) AS 'Referrer (IP:First)', t1.referer_url AS 'Referrer URL' FROM piwik_log_visit t1, piwik_log_conversion t2 WHERE t1.idvisitor = t2.idvisitor AND t2.idorder IS NOT NULL AND t2.server_time BETWEEN '2015-11-25 07:59:59' AND '2015-11-26 08:00:00' AND t1.visit_first_action_time >= (@theDate - INTERVAL 32 DAY) GROUP BY t2.idorder