Оптимизация этих вложенных операторов IN с использованием JOIN в MySQL - PullRequest
0 голосов
/ 03 апреля 2019

Я пишу запрос, чтобы исключить определенную группу сотрудников из таблицы.Допустим, у меня есть таблица 1 ,action_details, в которой есть информация, которую я хочу выбрать.Таблица 2 employee_task_associations отображает каждого сотрудника в задачу, для которой он был назначен в определенный день.У него есть поле для employee_id и поле с именем map_id, которое является идентификатором различных задач.Эта таблица является ассоциативной, поэтому таблицы 1 и 3 могут иметь отношение «многие ко многим».Таблица 3 employee_tasks содержит список всех задач, которые может выполнять сотрудник.

Я написал этот запрос, который работает, но не оптимизирован:

SELECT someInfo FROM transaction_details TD
WHERE TD.employee_id NOT IN
  (SELECT employee_id from employee_task_associations ETA
    WHERE map_id IN
      (SELECT id FROM employee_tasks ET
       WHERE ET.taskName = "The task I want to exclude"))

Пока это работает,он будет выполнять несколько запросов.Я хочу ускорить процесс, заменив мои вложенные операторы NOT IN и IN на JOINS.

Я знаю, что могу заменить нижние четыре строки следующим:

SELECT employee_id FROM employee_task_assocations ETA
  LEFT OUTER JOIN employee_tasks ET
    ON ETA.map_id = ET.id
    WHERE ET.taskName = "The task I want to exclude"

Это вернетсписок всех идентификаторов сотрудников, которые выполнили эту задачу.Я хочу исключить их из моего оператора SELECT из транзакции за счет использования JOIN вместо подзапроса.Я попытался с помощью LEFT OUTER JOIN WHERE ETA.id NULL, но это не работает.Как я могу использовать JOIN для исключения определенных сотрудников в этом случае?

Ответы [ 2 ]

1 голос
/ 03 апреля 2019

Вы, кажется, близки к своему первоначальному запросу, но почему бы не присоединить запрос NOT IN и получить отдельных сотрудников ... Что-то вроде

SELECT 
      TD.someInfo 
   FROM 
      transaction_details TD
   WHERE 
      TD.employee_id NOT IN
         (SELECT DISTINCT
                employee_id 
             from 
                employee_task_associations ETA
                   JOIN employee_tasks ET
                      ON ETA.map_id = ET.ID
                      AND ET.taskName = "The task I want to exclude")
0 голосов
/ 03 апреля 2019

Кажется, вы думаете, что внешнее объединение более производительно, чем подзапрос, но это не так.Все зависит от планировщика SQL, оптимизатора SQL, существующих индексов, статистики таблиц и, безусловно, от набора операторов данных, предлагаемых вашим механизмом базы данных.

Кроме того, следует учитывать, что после синтаксического анализа запрос вводится в фаза преобразования , где ядро ​​базы данных может переписать ваш запрос более эффективным способом.Это означает, что за кулисами ваш запрос может фактически выполняться с использованием внешних объединений, даже если вы пишете подзапросы.После этого [переписанный] запрос поступает в планировщик запросов, а затем в оптимизатор SQL.

Единственный способ его оптимизации - получить план выполнения всех параметров запроса и сравнить их.

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