带有子查询优化的sql查询

时间:2015-11-30 20:27:25

标签: mysql sql database subquery matomo

我是SQL的初学者,我的子查询存在问题。我设置子查询的原因是我需要对列进行排序和分组,而不是在主表上对数据进行排序。有没有其他方法来优化此查询?它已超时并且已运行超过30分钟。我想尽量避免重新扫描piwik_log_visit表。有没有办法按订单或按特定列排序?我感谢任何帮助。谢谢!

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

2 个答案:

答案 0 :(得分:1)

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

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

WHERE t1.idvisitor = t2.idvisitor

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

答案 1 :(得分:0)

尝试不使用 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