Должны ли критерии дублироваться на подзапросах - PullRequest
1 голос
/ 10 ноября 2010

У меня есть запрос, который фактически выполняет два запроса к таблице.Я запрашиваю всю таблицу, дату и затем подзапрос, который сообщает мне сумму часов, которые каждая единица провела на определенных этапах работы.Основной запрос ограничивает результаты хранилищем REP, поэтому технически мне не нужно ставить те же критерии в подзапросе, так как repair_order уникален.

Будет ли быстрее, медленнее или нет разницы применять фильтр депо к подзапросу?

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 голосов
/ 10 ноября 2010

Ответ на ваш вопрос будет варьироваться в зависимости от вашей схемы, сложности ваших запросов, надежности ваших данных и т. Д. Общее практическое правило - попытаться обработать как можно меньше данных, что обычно означает фильтрацию это на самом низком возможном уровне.

Когда вы хотите оптимизировать запрос, абсолютное число, с которого нужно начинать, это использовать вывод EXPLAIN , чтобы увидеть, какие оптимизации анализатор запросов смог выяснить, и проверить, что является самой слабой ссылкой в плане запроса. Разрешите это, промойте, повторите.

Вы также можете использовать «расширенное» ключевое слово объяснения, чтобы увидеть фактический запрос, который он построил для выполнения, что позволит узнать больше об использовании ваших критериев. В некоторых случаях это оптимизирует дублирование условий между родителями / подзапросами. В других случаях это может подтолкнуть условия от родителя к подзапросу. В некоторых случаях для (слишком) сложных запросов я видел, как оно повторяет условие, когда оно было указано в запросе только один раз. К счастью, вам не нужно догадываться, план объяснения mysql покажет все, хотя иногда и загадочно.

0 голосов
/ 10 ноября 2010

Я обычно использую производную таблицу в качестве запроса «драйвера или агрегирования», затем присоединяю этот результат к любой таблице, из которой я хочу получить данные:

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;
0 голосов
/ 10 ноября 2010

В этом примере это фактически изменило бы запрос, если бы вы переместили свое предложение WHERE для фильтрации по REP в подзапрос. Таким образом, речь идет не о производительности, а о получении того же набора результатов. В общем, однако, если вы получите тот же точный набор результатов, переместив предложение WHERE в другое место в сложном запросе, лучше сделать это на самом атомарном уровне, то есть в подзапросе. Затем подзапрос возвращает меньший набор результатов в основной запрос, прежде чем основной запрос должен его обработать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...