应该在子查询上重复标准

时间:2010-11-10 13:21:50

标签: mysql subquery

我有一个查询,它实际上在一个表上运行两个查询。我查询整个表格,一个日期,然后是一个子查询,它告诉我每个单位在某些操作步骤中花费的小时数。主查询将结果限制在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;

我遇到很多情况但是我不知道将过滤器放在子查询,主查询或两者中是否更好。

3 个答案:

答案 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;