Оптимизация множественного левого соединения

0

столы:

  • работник
  • employee_orgn
    • Объединенный первичный ключ (employee_id, orgn_id)
    • два индекса: key1: employee_id, index2: orgn_id
  • orgn

У некоторых сотрудников нет организации.

SQL:

explain SELECT DISTINCT
    e.*
FROM
    employee e
        LEFT JOIN
    employee_orgn eo ON eo.employee_id = e.id
        LEFT JOIN
    orgn o ON o.id = eo.orgn_id
WHERE
    e.state != 'deleted'
        AND e.state != 'hidden'
        AND (o.state != 'hidden' OR o.state IS NULL)
ORDER BY e.id DESC

Объясняю:

| id   | select_type    |  table | type | possible_keys | key  | key_len | ref  | rows | Extra |

| 1        | SIMPLE     |   e    |all        | NULL     |   NULL    |NULL        | NULL      |   12792    |Using where;USing tempory;Using filesort       | 

| 1        | SIMPLE     |   eo    |index        | PRIMARY     |   idx_orgn_id    |8        | NULL     |   13226  |Using index:Distinct  | 

| 1        | SIMPLE     |   o    |eq_ref        | PRIMARY      |   PRIMARY    |8        | eo.orgn_id      |   1    |Using where:Distinct           | 

Q:

  1. Здесь left join, mysql вложенный запрос циклы 10 порядков 8?
  2. Почему существуют временные таблицы, и почему сортировка - сортировка файлов?
  3. Почему вторая строка - это оверлейный индекс
  4. Надеюсь, кто-то объяснит это объяснение и оптимизирует анализ.

Заранее спасибо.

  • 0
    Пожалуйста, объясните, что вы хотите сделать запрос.
  • 0
    Показать структуры таблиц SHOW CREATE TABLE table для каждой таблицы, связанной с вопросом. "Почему существуют временные таблицы и почему сортировка - это сортировка файлов?" сортировка файла - это «плохое» имя в файле объяснения .. сортировка означает, что она использует быструю сортировку в таблице памяти. Если таблица памяти слишком велика, то вы получите быструю сортировку таблицы на основе диска.
Показать ещё 1 комментарий
Теги:

2 ответа

0
Лучший ответ

Я бы рекомендовал повторно написать запрос - чтобы избавиться от выделенного select distinct. Я думаю, что это логика, которую вы хотите:

SELECT e.*
FROM employee e
WHERE e.state not in ('deleted', 'hidden')
      NOT EXISTS (SELECT 1
                  FROM employee_orgn eo JOIN
                       orgn o
                       ON o.id = eo.orgn_id AND o.state = 'hidden'
                  WHERE eo.employee_id = e.id
                 )
ORDER BY e.id DESC;

Для этого запроса вам нужен индекс для employee_orgn(employee_id, orgn_id) и orgn(id, state).

  • 0
    Вы пропускаете FROM в вашем внешнем SELECT .
  • 0
    Спасибо, вы можете помочь мне проанализировать предыдущий SQL объяснить
Показать ещё 1 комментарий
0

Вы не должны ставить условия на таблицы, которые остались объединенными в WHERE. Вместо этого поместите их в предложение ON. Тогда вам не нужно использовать OR o.state IS NULL, что вызывает проблемы с оптимизатором.

SELECT DISTINCT
    e.*
FROM
    employee e
        LEFT JOIN
    employee_orgn eo ON eo.employee_id = e.id
        LEFT JOIN
    orgn o ON o.id = eo.orgn_id AND o.state != hidden
WHERE
    e.state NOT IN ('deleted', 'hidden')
ORDER BY e.id DESC

Ещё вопросы

Сообщество Overcoder
Наверх
Меню