SQL Server - альтернатива существующим (слишком много подзапросов) - PullRequest
0 голосов
/ 20 сентября 2018

Я ищу способ повысить производительность запроса, который имеет слишком много существующих связанных подзапросов.

Моя проблема заключается в том, что у меня есть таблица сведений о заказах, в которой для каждого элемента заказа естьопределенная категория (хранится в другой таблице, но это не имеет значения сейчас).

Мне нужно обнаружить определенную «группу» заказов на основе различных комбинаций этих категорий: - Группа A: Заказы с элементами по категориям13 + 15 + любой из (66, 67, 68, 69) заказов с элементами по категориям 77 + 78 + любой из (66, 67, 68, 69, 71, 71)

Что я сделалДо сих пор существует ОГРОМНЫЙ запрос со связью, чтобы найти заказы, которые соответствуют этим критериям, но это кошмар производительности.

Я надеюсь, что есть лучший способ сделать это, потому что в моей таблице миллионы записей ...

Большое спасибо !!!

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Я бы использовал group by и having:

select order_id
from order_details od
group by order_id
having sum(case when category = 13 then 1 else 0 end) > 0 and  -- at least one 13
       sum(case when category = 15 then 1 else 0 end) > 0 and  -- at least one 15
       sum(case when category in (66, 67, 68, 69) then 1 else 0 end) > 0  -- at least one of these

Это можно легко расширить.Итак, для второй группы:

having (sum(case when category = 13 then 1 else 0 end) > 0 and  -- at least one 13
        sum(case when category = 15 then 1 else 0 end) > 0 and  -- at least one 15
        sum(case when category in (66, 67, 68, 69) then 1 else 0 end) > 0    
       ) or
       (sum(case when category = 77 then 1 else 0 end) > 0 and  -- at least one 13
        sum(case when category = 78 then 1 else 0 end) > 0 and  -- at least one 15
        sum(case when category in (66, 67, 68, 69, 71, 71) then 1 else 0 end) > 0    
       ) 
0 голосов
/ 20 сентября 2018

Непонятно, как структурирована ваша база данных, но вы можете попробовать что-то похожее на это:

SELECT DISTINCT
       orders.order_id AS group_a_order
FROM   orders
JOIN   order_details od13
  ON   orders.order_id = od13.order_id
 AND   od13.category = 13
JOIN   order_details od15
  ON   orders.order_id = od15.order_id
 AND   od15.category = 15
JOIN   order_details od6x
  ON   orders.order_id = od6x.order_id
 AND   od6x.category IN (66, 67, 68, 69)

Возвращает все ордера, которые имеют:
- как минимум 1 деталь категории 13 и
- как минимум 1 деталь категории 16 и
- как минимум 1 деталь категории 66, 67, 68 или 69

...