Как оптимизировать запрос условного выбора, который включает в себя внутренние объединения? - PullRequest
0 голосов
/ 27 сентября 2019

У меня есть SQL-запрос, в котором есть много ВНУТРЕННИХ СОЕДИНЕНИЙ между другими таблицами.

Я знаю, что мы можем использовать соединения для оптимизации, но, как мы видим, этот запрос уже включал соединения в него.Я думал добавить GROUP BY к этому утверждению, которое становится более реалистичным и может работать лучше.Вызывает ли медленный запрос выбор нескольких столбцов из одной таблицы в другую?Если так, как это могло бы работать, если мы должны оптимизировать?Ниже мой код:

SELECT /*PARALLEL(4)*/
    s.task_seq_num,
    s.group_seq_num AS grp_seq_num,
    g.source_type_cd,
    d.doc_id,
    d.doc_ref_id AS doc_ref_id,
    dm.doc_priority_num AS doc_priority,
    s.doc_seq_num AS doc_seq_num,
    s.case_num AS case_num,
    dm.doc_title_name AS doc_title,
    s.task_status_cd AS task_status_cd,
    d.received_dt AS received_dt,
    nvl(b.first_name,d.first_name) AS first_name,
    nvl(b.mid_name,d.mid_name) AS mid_name,
    nvl(b.last_name,d.last_name) AS last_name,
    tg.content_tag_cd AS content_tag_cd,
    d.app_num AS app_num,
    e.head_of_household_sw AS head_of_household_sw,
    f.user_id AS user_id
FROM
    dm_task_status s
    INNER JOIN dm_task_tag tg ON s.task_seq_num = tg.task_seq_num
    INNER JOIN dm_doc_group g ON g.group_seq_num = s.group_seq_num
    INNER JOIN dm_doc d ON d.doc_seq_num = s.doc_seq_num
    INNER JOIN dm_doc_master dm ON dm.doc_ref_id = d.doc_ref_id
    LEFT JOIN mo_employees f ON f.emp_id = s.emp_id
    LEFT JOIN ( dc_case_individual e
    INNER JOIN dc_indv b ON b.indv_id = e.indv_id
                            AND e.head_of_household_sw = 'Y' ) ON e.case_num = s.case_num
WHERE
    s.office_num =38
    AND   s.eff_end_tms IS NULL
    AND   d.delete_sw IS NULL
ORDER BY s.group_seq_num ASC;

Любые идеи приветствуются

1 Ответ

0 голосов
/ 27 сентября 2019

Во-первых,

AND   d.delete_sw IS NULL

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

Во-вторых, поскольку мы не знаем сами данные или структуру данных, я бы сказал,при КАЖДОМ соединении убедитесь, что вы по возможности используете индекс таблицы, чтобы предотвратить полное сканирование таблицы.Это может показаться оскорбительным, но я неоднократно совершал ошибку, не осознавая, что на самом деле было место, где я НЕ использовал индексированное поле для ограничения сканируемых данных.

Например, все ли поля, перечисленные ниже, являются частью первичного ключа соответствующих таблиц?Если да, то они ПОЛНЫЙ первичный ключ?Если они не являются полным первичным ключом, есть ли способ получить остальные значения первичного ключа из таблиц, из которых вы «исходите»?SQL постарается сделать все возможное, чтобы составить наиболее эффективный план, но он может зайти так далеко, что мы всегда должны стараться убедиться, что мы используем индексированные поля и, предпочтительно, первичные ключи, чтобы база данных недолжны работать усерднее, чем должны.

Обсуждаемые поля:

dm_task_tag.task_seq_num
dm_doc_group.group_seq_num
dm_doc.doc_seq_num
dm_doc_master.dm.doc_ref_id
mo_employees.emp_id
dc_case_individual.indv_id
dc_case_individual.case_num

Я ОЧЕНЬ с подозрением отношусь ко второму левому соединению, но я не могу сказать об этом много, не зная таблиц.Мне также особенно любопытно, является ли doc_ref_id на самом деле первичным ключом dm_doc_master, или если у вас есть seq_num, которого вам не хватает ...

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