我有一个查询,它实际上在一个表上运行两个查询。我查询整个表格,一个日期,然后是一个子查询,它告诉我每个单位在某些操作步骤中花费的小时数。主查询将结果限制在REP库中,因此从技术上讲,我不需要在子查询上添加相同的条件,因为repair_order是唯一的。
在子查询上应用depot过滤器会更快,更慢或没有区别吗?
SELECT
*,
DATEDIFF(date_shipped, date_received) as htg_days,
(SELECT SUM(t3.total_days) FROM report_tables.cycle_time_days as t3 WHERE t1.repair_order=t3.repair_order AND (operation='MFG' OR operation='ENG' OR operation='ENGH' OR operation='HOLD') GROUP BY t3.repair_order) as subt_days
FROM
report_tables.cycle_time_days as t1
WHERE
YEAR(t1.date_shipped)=2010
AND t1.depot='REP'
GROUP BY
repair_order
ORDER BY
date_shipped;
我遇到很多情况但是我不知道将过滤器放在子查询,主查询或两者中是否更好。
答案 0 :(得分:0)
在此示例中,如果您移动WHERE子句以按REP过滤到子查询中,它实际上会更改查询。所以它不是关于那时的性能,而是关于获得相同的结果集。但是,一般情况下,如果通过在复杂查询中的其他位置移动WHERE子句来获得相同的精确结果集,则最好在尽可能最原子的级别(即子查询)中执行此操作。然后子查询在主查询必须处理之前将较小的结果集返回给主查询。
答案 1 :(得分:0)
您的问题的答案将根据您的架构,查询的复杂性,数据的可靠性等而有所不同。一般的经验法则是尝试处理尽可能少的数据,这通常意味着过滤它也处于最低水平。
当您想要优化查询时,绝对最开始的地方是使用EXPLAIN output来查看查询解析器能够找出哪些优化,并检查查询中最弱的链接是什么计划。解决,冲洗,重复。
您还可以使用explain的“extended”关键字来查看它为运行而构建的实际查询,这将显示有关其标准用法的更多信息。在某些情况下,它会优化父/子查询之间的重复条件。在其他情况下,它可能会将条件从父级推送到子查询。在某些情况下,对于(太)复杂的查询,我看到它只重复了一次只在查询中指定的条件。值得庆幸的是,你不必猜测,mysql的解释计划将揭示所有,尽管有时会以神秘的方式。
答案 2 :(得分:0)
我通常使用派生表作为“驱动程序或聚合”查询,然后将该结果连接到我想从中提取数据的任何表:
select
t1.*,
datediff(t1.date_shipped, t1.date_received) as htg_days,
subt_days.total_days
from
cycle_time_days as t1
inner join
(
-- aggregating/driver query
select
repair_order,
sum(total_days) as total_days
from
cycle_time_days
where
year(date_shipped) = 2010 and depot = 'REP' and
operation in ('MFG','ENG','ENGH','HOLD') -- covering index on date, depot, op ???
group by
repair_order -- indexed ??
having
total_days > 14 -- added for demonstration purposes
order by
total_days desc limit 10
) as subt_days on t1.repair_order = subt_days.repair_order
order by
t1.date_shipped;