Нужна помощь для настройки сложного запроса - PullRequest
0 голосов
/ 30 мая 2019

Я пытаюсь настроить производительность запроса, и нам нужна помощь с этим

У нас есть требование извлекать данные на веб-сайте на основе нескольких факторов, которые привели к сложному запросу, который работает нормально, но стоит дорого.У нас есть все правильные показатели.

Я застрял в том, чтобы исключить использование DISTINCT в запросе (что, похоже, является узким местом).

Я не эксперт по SQL и думаю, что перепробовал все, что мог.

Будем весьма благодарны за любую помощь, чтобы упростить этот запрос и удалить DISTINCT (или не использовать GROUP BY).Спасибо.

SELECT DISTINCT  t2.PK  
FROM categories t0 
    JOIN cat2catrel t1 ON  t1.SourcePK  =  t0.PK  
    JOIN categories t2 ON  t1.TargetPK  =  t2.PK  
    JOIN cat2catrel t3 ON  t3.SourcePK  =  t2.PK  
    JOIN categories t4 ON  t3.TargetPK  =  t4.PK  
    JOIN cat2prodrel t5 ON  t5.SourcePK = t4.PK  
    JOIN products t6 ON  t5.TargetPK  =  t6.PK  
    JOIN stocklevels t7 ON  t7.productcode  =  t6.code  
    JOIN relativeinventory t8 ON  t7.p_inventory  =  t8.PK  
    JOIN warehouses t9 ON  t7.warehouse  =  t9.PK  
    JOIN pos2warehouserel t10 ON  t10.TargetPK  =  t9.PK  
    JOIN pos2warehouserel t10 ON  t10.TargetPK  =  t9.PK  
    JOIN pointofservice item_t11 ON  t10.SourcePK  =  t11.PK  
    WHERE  ( t0.code  = 'code' 
        AND  t8.nventorystatus  IN (1111) 
        AND  t11.name  = 'ABC') 
        AND ((t0.TypePkString IN  (1, 2, 3, 4)  
        AND (( t0.catalogversion  IN (1, 2, 3)))  
        AND t1.TypePkString=1000 
        AND t2.TypePkString IN  (1, 2, 3, 4)  
        AND (( t2.catalogversion  IN (1, 2)))  
        AND t3.TypePkString=300  
        AND t4.TypePkString IN  (6, 7, 8)  
        AND (( t4.catalogversion  IN (5, 6)))  
        AND t5.TypePkString=500 
        AND t6.TypePkString=600 
        AND t7.TypePkString=200  
        AND t8.TypePkString=700 
        AND t9.TypePkString IN  (3, 7)  
        AND t10.TypePkString=900  
        AND t11.TypePkString=750 ));

В настоящее время этот запрос работает нормально и дает желаемые результаты.Я просто не хочу использовать DISTINCT или GROUP BY и все же получаю уникальные результаты.

БД: MySQL 6.3

1 Ответ

0 голосов
/ 30 мая 2019

Ваш единственный выбор t2.pk, который представляется первичным ключом в таблице категорий. Если это правильно, то вы производите дублирование со своими Joins. В общем, проще всего избавиться от DISTINCT в этом сценарии - начать с таблицы, из которой вы выбираете, и убедиться, что ваше ВНУТРЕННЕЕ СОЕДИНЕНИЕ к нему. Тем не менее, кажется, что вы на самом деле уже делаете это, но вы дублируете соединение ... то есть t0 и t2 - это одна и та же таблица, которая для меня - большой красный флаг. Попробуйте что-то вроде этого:

SELECT t0.PK  
FROM categories t0 
    INNER JOIN cat2catrel t1 ON  t1.SourcePK  =  t0.PK AND t1.TargetPK = t0.PK
    INNER JOIN cat2catrel t3 ON  t3.SourcePK  =  t0.PK  
    INNER JOIN categories t4 ON  t3.TargetPK  =  t4.PK  
    INNER JOIN cat2prodrel t5 ON  t5.SourcePK = t4.PK  
    INNER JOIN products t6 ON  t5.TargetPK  =  t6.PK  
    INNER JOIN stocklevels t7 ON  t7.productcode  =  t6.code  
    INNER JOIN relativeinventory t8 ON  t7.p_inventory  =  t8.PK  
    INNER JOIN warehouses t9 ON  t7.warehouse  =  t9.PK  
    INNER JOIN pos2warehouserel t10 ON  t10.TargetPK  =  t9.PK  
    INNER JOIN pos2warehouserel t10 ON  t10.TargetPK  =  t9.PK  
    INNER JOIN pointofservice item_t11 ON  t10.SourcePK  =  t11.PK  
    WHERE  ( t0.code  = 'code' 
        AND  t8.nventorystatus  IN (1111) 
        AND  t11.name  = 'ABC') 
        AND ((t0.TypePkString IN  (1, 2, 3, 4)  
        AND (( t0.catalogversion  IN (1, 2, 3)))  
        AND t1.TypePkString=1000 
        AND t2.TypePkString IN  (1, 2, 3, 4)  
        AND (( t2.catalogversion  IN (1, 2)))  
        AND t3.TypePkString=300  
        AND t4.TypePkString IN  (6, 7, 8)  
        AND (( t4.catalogversion  IN (5, 6)))  
        AND t5.TypePkString=500 
        AND t6.TypePkString=600 
        AND t7.TypePkString=200  
        AND t8.TypePkString=700 
        AND t9.TypePkString IN  (3, 7)  
        AND t10.TypePkString=900  
        AND t11.TypePkString=750 ));

Однако я вижу, что другие таблицы продублированы как «pos2warehouserel». Таблицы должны объявляться и присваиваться псевдоним только один раз.

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