使用子查询、IF和join优化MySQL查询
我有一个复杂的SQL语句,每次调用都需要0.35秒。有50个用户和2周的日历项目,需要245秒,这太长了。我试图优化查询,但目前我还不知道 我对所有相关列都有索引使用子查询、IF和join优化MySQL查询,mysql,Mysql,我有一个复杂的SQL语句,每次调用都需要0.35秒。有50个用户和2周的日历项目,需要245秒,这太长了。我试图优化查询,但目前我还不知道 我对所有相关列都有索引 SELECT DISTINCT tax.ta_id, tax.a_id, ax.status, ax.kunden_id, IF(ax.todo_from != '0000-00-00', DATE_FORMAT(ax.todo_from, '%d.%m'), 'k. day_date') todo_fro
SELECT
DISTINCT tax.ta_id, tax.a_id, ax.status, ax.kunden_id,
IF(ax.todo_from != '0000-00-00', DATE_FORMAT(ax.todo_from, '%d.%m'), 'k. day_date') todo_from,
IF(ax.todo_until != '0000-00-00', DATE_FORMAT(ax.todo_until, '%d.%m'), 'k. day_date') todo_until,
IF((SELECT taj.city FROM suborders taj WHERE taj.a_id = tax.a_id AND taj.order_type = 'BRING' ORDER BY pos_id ASC LIMIT 1) != '', CONCAT(IF((SELECT short_name FROM locations WHERE company_id = '100' AND h_id = tax.h_id) != '', (SELECT short_name FROM locations WHERE company_id = '100' AND h_id = tax.h_id),tax.city),'>', CONCAT((SELECT IF((SELECT short_name FROM locations WHERE company_id = '100' AND h_id = taj.h_id) != '', (SELECT short_name FROM locations WHERE company_id = '100' AND h_id = taj.h_id), taj.city) FROM suborders taj WHERE taj.a_id = tax.a_id AND taj.order_type = 'BRING' AND taj.pos_id >= tax.pos_id ORDER BY pos_id ASC LIMIT 1))), IF((SELECT short_name FROM locations WHERE company_id = '100' AND h_id = tax.h_id) != '', (SELECT short_name FROM locations WHERE company_id = '100' AND h_id = tax.h_id),tax.city)) as city,
tax.user_id, tax.day_date, tax.pos_gesamt_id, '4' as class_type
FROM
suborders tax INNER JOIN orders ax ON (ax.a_id = tax.a_id)
WHERE
tax.order_type = 'TAKE' AND tax.user_id = '140' AND (tax.day_date = '2013-04-16' AND '2013-04-16' = (SELECT taj.day_date FROM suborders taj WHERE taj.a_id = tax.a_id AND taj.user_id = '140' AND taj.day_date = '2013-04-16' AND taj.user_id = '140' AND taj.order_type = 'BRING' ORDER BY pos_gesamt_id ASC)) AND tax.company_id = '100' GROUP BY tax.ta_id
也许您可以给我一些建议。第一次尝试重写(未经测试,因为我不知道您的表格布局):- 在这一阶段,我不确定我能不能进一步做到这一点,因为这真的让我很困惑事情是如何结合在一起的 问题是,您有很多相关的子查询,而且这些子查询速度很慢(即,子查询依赖于查询外部的字段,因此MySQL必须对每一行执行该子查询)。我已经删除了几个我可以解决的问题,并将它们替换为子查询的连接(使用这些子查询,MySQL可以执行一次子查询,然后将结果连接到主查询) 但是,当您在查询中关联子查询,并且在不同的表和子查询之间重用别名时,会非常混乱 如果我能计算出查询的目的,那么查询的性能将大大提高
此外,还对主查询使用了GROUPBY,但没有任何聚合列。有时这会代替DISTINCT,但您也有DISTINCT。您也有组合索引吗?没有,这有什么帮助?这个索引应该包括哪些列?您有很多相关的子查询,这些子查询的性能都可能很差。我正在努力弄清楚你是如何让city字段尝试并重新编码的,如果你解释一下你的查询应该做什么,如果你解释一下表的结构,如果你展示了一个预期结果的示例,你可能会收到更多的答案。目前,您的查询很难理解。
SELECT DISTINCT tax.ta_id, tax.a_id, ax.status, ax.kunden_id,
IF(ax.todo_from != '0000-00-00', DATE_FORMAT(ax.todo_from, '%d.%m'), 'k. day_date') todo_from,
IF(ax.todo_until != '0000-00-00', DATE_FORMAT(ax.todo_until, '%d.%m'), 'k. day_date') todo_until,
IF((SELECT taj.city FROM suborders taj WHERE taj.a_id = tax.a_id AND taj.order_type = 'BRING' ORDER BY pos_id ASC LIMIT 1) != '',
CONCAT(
IF(Sub2.short_name != '', Sub2.short_name,tax.city),
'>',
CONCAT((
SELECT IF( Sub3.short_name != '',
Sub3.short_name,
taj.city)
FROM suborders taj
LEFT OUTER JOIN (SELECT h_id, short_name FROM locations WHERE company_id = '100') Sub3 ON Sub3.h_id = taj.h_id
WHERE taj.a_id = tax.a_id
AND taj.order_type = 'BRING'
AND taj.pos_id >= tax.pos_id
ORDER BY pos_id
ASC LIMIT 1))),
IF(Sub2.short_name != '', Sub2.short_name, tax.city)) as city,
tax.user_id, tax.day_date, tax.pos_gesamt_id, '4' as class_type
FROM suborders tax
INNER JOIN orders ax ON (ax.a_id = tax.a_id)
INNER JOIN (
SELECT DISTINCT a_id
FROM suborders taj
WHERE taj.user_id = '140'
AND taj.day_date = '2013-04-16'
AND taj.user_id = '140'
AND taj.order_type = 'BRING'
) Sub4 ON Sub4.a_id = tax.a_id
LEFT OUTER JOIN (SELECT h_id, short_name FROM locations WHERE company_id = '100') Sub2 ON Sub2.h_id = tax.h_id
WHERE tax.order_type = 'TAKE'
AND tax.user_id = '140'
AND tax.day_date = '2013-04-16'
AND tax.company_id = '100'
GROUP BY tax.ta_id