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
解释计划:
性能不佳的主要原因是表之间的连接条件。由于涉及的列上的数据转换,它们无法使用索引进行优化。如果没有索引,连接将成为笛卡尔连接,然后通过计算连接表达式来过滤。
为什么需要在 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
我是 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
解释计划:
性能不佳的主要原因是表之间的连接条件。由于涉及的列上的数据转换,它们无法使用索引进行优化。如果没有索引,连接将成为笛卡尔连接,然后通过计算连接表达式来过滤。
为什么需要在 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