Улучшение производительности запросов - PullRequest
0 голосов
/ 12 октября 2018

Здесь две таблицы, по-разному классифицирующие одни и те же элементы (TBL1.ID и TBL2.Code) (Grp и Cat).

Каждый элемент принадлежит только одной группе (с разными именами групп в двух таблицах).в TBL2 есть подмножество элементов в TBL1

Пропущенные элементы только существующих котов в TBL2 с необходимым котом (A4 не требуется)

TBL1:

    Grp         ID
--------------------
    X1          A1        
    X1          B1        
    X1          C1        
    X1          D1        
    X2          A2        
    X2          B2        
    X2          C2        
    X2          D2        
    X3          A3        
    X3          B3        
    X4          A4        

TBL2:

   Cat         Code
--------------------
    1           A1        
    1           B1        
    1           C1        
    2           A2        
    2           B2        
    3           A3        
    5           A5        

Желаемый:

    ID         Grp         Cat        
---------------------------------
    D1          X1          1         
    C2          X2          2         
    D2          X2          2         
    B3          X3          3         

Этот запрос работает нормально, но для большого количества записейслишком медленно:

SELECT
  TBL1.ID
  ,TBL1.Grp
  ,(SELECT DISTINCT T2.Cat FROM TBL2 T2 WHERE T2.Code IN
  (SELECT T1.ID FROM TBL1 T1 WHERE T1.Grp = TBL1.Grp )) AS Cat

FROM TBL1
LEFT JOIN TBL2
ON TBL1.ID = TBL2.Code
WHERE TBL2.Code IS NULL
AND (SELECT DISTINCT T2.Cat FROM TBL2 T2 WHERE T2.Code IN
    (SELECT T1.ID FROM TBL1 T1 WHERE T1.Grp = TBL1.Grp ))  IS NOT NULL

Любое решение с лучшей производительностью приветствуется.

1 Ответ

0 голосов
/ 12 октября 2018

Оригинальный подзапрос имеет большой недостаток: он предназначен для того, чтобы иметь возможность возвращать более одного значения, но это нарушит весь запрос.Измените ваши данные таким образом, чтобы любая группа была подключена к нескольким категориям, и она потерпит неудачу (например, (1, 'A1') -> (2, 'A1')).DISTINCT помогает избежать сбоев с данными примера, но не может помочь при различных значениях.

И вы не указали, какую категорию выбрать, если более одной соответствует группе.Я использовал MAX:

SELECT
  t.ID
  ,t.Grp
  ,c.Cat
FROM TBL1 t
INNER JOIN (
  SELECT g.Grp, MAX(c.Cat) Cat 
  FROM TBL1 g
  INNER JOIN TBL2 c
  ON c.Code = g.ID
  GROUP BY g.Grp
) c
ON c.Grp = t.Grp
WHERE NOT EXISTS(SELECT 1 FROM TBL2 t2 WHERE t2.Code = t.ID)

здесь TBL1 присоединяется к списку всех групп, связанных с любой категорией .INNER JOIN сохранит только группы, которые связаны хотя бы с одной категорией (эквивалентно вашей NOT NULL).И я заменил ваш LEFT JOIN на NOT EXISTS, потому что это более легкая операция для SQL SERVER, а результаты у него такие же.

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