@zakharoffam
Начинающий

Как оптимизировать вот такой SQL-запрос?

Получил в наследство вот такой SQL-запрос:
spoiler
SELECT task.[ID],
    task.[OPEN_TIME],
    task.[TIME_BREACH],
    task.[PRIORITY],
    task.[IS_MASS],
    task.[IS_VSP],
    task.[REASSIGN],
    task.[LOCATION_FULL_NAME],
    task.[DESCRIPTION],
    task.[AUDIT_WORKGROUP],
    task.[SERVICE],
    task.[CONTACT_NAME],
    mobile.[MOBILE],
    phone.[PHONE],
    email.[EMAIL],
    task.[LOCATION],
    iparm.[IP_ARM],
    ipmfu.[IP_MFU],
    level.[LEVEL],
    additionally.[OPERATION_TIME],
    domain.[DOMAIN],
    pcname.[PC_NAME],
    task.[INFO],
    comment.[COMMENT],
    uz.[UZ],
    task.[SOLUTION],

CASE WHEN task.[INFO] LIKE '% вирус%' OR comment.[COMMENT] LIKE '% вирус%' THEN 1 ELSE 0 END VIRUS,

CASE WHEN LOWER(task.PRIORITY) LIKE '%высокий%' OR IS_MASS = 't' OR LOWER(task.PRIORITY) LIKE '%очень важно%' OR LOWER(task.PRIORITY) LIKE '%критический%' OR LOWER(task.PRIORITY) LIKE '%широкомасштабный%' THEN 5
WHEN LOWER(task.SOLUTION) LIKE '%#mos%' OR LOWER(task.SOLUTION) LIKE '%масс_раб%' OR LOWER(task.SOLUTION) LIKE '%мас_раб%' THEN 4
WHEN LOWER(task.INFO) LIKE '%ЕР%' OR LOWER(task.INFO) LIKE '% вирус%' OR LOWER(task.INFO) LIKE '% массов%' OR LOWER(task.PRIORITY) LIKE '%высокий%' OR IS_MASS = 't' THEN 3
WHEN LOWER(task.INFO) LIKE '% все%' OR LOWER(task.INFO) LIKE '%ни у кого%' THEN 2
WHEN task.ID IN (SELECT id_task FROM Priority_task_logs WHERE tag = '#РГК') THEN 1
ELSE 0 END AS [ORDER_PRIORITY]

FROM [Task_on_null] task

LEFT JOIN (
SELECT [SELECTED_VAL] AS [MOBILE], [ID_TASK]
FROM [Shablons_DopParametrs]
WHERE [LABEL] LIKE '%Мобильный телефон%'
)
mobile ON task.[ID] = mobile.[ID_TASK]

LEFT JOIN (
SELECT [SELECTED_VAL] AS [PHONE],  [ID_TASK]
FROM [Shablons_DopParametrs]
[LABEL] LIKE '%Внутренний телефон%'
)
phone ON task.ID = phone.[ID_TASK]

LEFT JOIN [portal_SMREP_loc] email ON task.[CONTACT_NAME] = email.[CONTACT_NAME]

LEFT JOIN (
SELECT [SELECTED_VAL] AS [IP_ARM], [ID_TASK]
FROM [Shablons_DopParametrs]
WHERE [LABEL] LIKE '%IP-адрес текущего АРМ%'
)
iparm ON task.ID = iparm.ID_TASK

LEFT JOIN (
[SELECTED_VAL] AS IP_MFU, [ID_TASK]
FROM [Shablons_DopParametrs]
WHERE [LABEL] LIKE '%IP адрес принтера/МФУ%'
)
ipmfu ON task.ID = ipmfu.ID_TASK

 // ....... тут еще куча JOIN'ов однотипных

LEFT JOIN (
[SELECTED_VAL] AS UZ, [ID_TASK]
FROM [Shablons_DopParametrs]
WHERE [LABEL] LIKE '%Учётная запись%' OR [LABEL] LIKE '%Логин%'
)
uz ON task.ID = uz.ID_TASK

ORDER BY [ORDER_PRIORITY] DESC


Есть две таблицы Task_on_null и Shablons_DopParametrs. В первой каждая строка имеет уникальное содержимое с неповторяющейся ID, во второй таблице три столбца, в ID_TASK тоже самое что и в первой таблице, только они как раз повторяются, но в других столбцах поля уникальные. Но работает очень медленно, нужно его оптимизировать.
Я пытаюсь написать что-то типа такого:
spoiler
SELECT 
    task.[ID],
    task.[OPEN_TIME],
    task.[TIME_BREACH],
    task.[PRIORITY],
    task.[IS_MASS],
    task.[IS_VSP],
    task.[REASSIGN],
    task.[LOCATION_FULL_NAME],
    task.[DESCRIPTION],
    task.[AUDIT_WORKGROUP],
    task.[SERVICE],
    task.[CONTACT_NAME],
    task.[LOCATION],
    task.[SB_TERBANK],
    task.[INFO],
    task.[SOLUTION],
    [MOBILE] = (
        CASE
            WHEN dop.[LABEL] LIKE '%Мобильный телефон%' AND dop.[ID_TASK] = task.[ID] THEN dop.[SELECTED_VAL]
            END)
FROM [Task_on_null] task

LEFT JOIN (
       SELECT [ID_TASK], [LABEL], [SELECTED_VAL]
       FROM [Shablons_DopParametrs] dop
       )
       dop ON task.[ID] = dop.[ID_TASK]


Но не правильно. В выборке дублируются ID, а должен быть уникальный, но с набором дополнительных столбцов.
  • Вопрос задан
  • 66 просмотров
Пригласить эксперта
Ответы на вопрос 2
dimonchik2013
@dimonchik2013
настоящие экстремалы предпочитают жен своих друзей
вот такое вот
LIKE '%что-то
тупо заставляет просмотреть весь столбец, все индексы до Ж
начать нужно с этого

ну и всякие slow queries log
Ответ написан
@d-stream
Готовые решения - не подаю, но...
Думаю стоит привести [Shablons_DopParametrs] из "человекочитаемого" в "компьютерочитаемый" вариант.
Например добавить некий тип label_type вместо того что в like и потом разово сделать
update [Shablons_DopParametrs]
set label_type = case 
          when [LABEL] LIKE '%Мобильный телефон%' then 1
          when [LABEL] LIKE '%Внутренний телефон%' then 2
          when [LABEL] LIKE '%IP-адрес текущего АРМ%' then 3
          when ....
          else null
end

а потом уже в отборах и join'ах использовать label_type

___________________________
и естественно не забыть и индекс по label_type
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
от 120 000 до 150 000 ₽
GANDIVA Нижний Новгород
от 100 000 до 190 000 ₽
ИНФИНИТУМ Москва
До 185 000 ₽
09 авг. 2020, в 18:16
200000 руб./за проект
09 авг. 2020, в 17:19
5000 руб./за проект