MySQL - основной запрос 2 таблицы медленно - где, индекс? - PullRequest
1 голос
/ 01 декабря 2010

У меня есть запрос MySQL 5.0, который обычно занимает 14+ секунд и вызывается с веб-страницы, и пользователи нетерпеливы. Это довольно просто, выбрав 11 столбцов из 2 таблиц. У меня три вопроса:

  1. Имеет ли значение объединение?
  2. Имеет ли значение порядок where, или MySQL оптимизируется?
  3. Поможет ли индекс в моем случае?

SQL:

select table1.id, table1.DateOpened, table1.Status, table2.Name, etc
from (table1 join table2 on((table1.CurrentName = table2.id))) 
where table1.Type = 'Add' and (Status = 'Open' OR Status = 'Pending');

информация о таблице / столбце:

table1 has 750,000 rows, table2 1.5M rows.
indexed: table1.id, table2.id
INT columns: id, table1.CurrentName
table1.Status = always populated with 1 of 4 values, 
                maybe 300 are 'Open' or 'Pending'
table1.Type = 3 possible values: 'Add', 'Change', or null
  1. Есть ли какое-либо преимущество присоединения в FROM по сравнению с добавлением 'table1.CurrentName = table2.id' в предложении WHERE?

  2. Есть 3 предложения WHERE (с объединением). Я запустил EXPLAIN с различными комбинациями заказов, и результаты оказались одинаковыми.

  3. Я думал, что добавление индекса в table1.CurrentName может помочь, но теперь я думаю, что нет. Я изменил запрос, чтобы удалить ссылки на table2, и он все еще работал медленно. (см. 3b)

  4. Похоже, что большая часть замедления может быть просто при чтении 800K записей, смотрящих на значения типа и состояния. Имеет ли смысл индексировать эти два столбца, где есть только 3 или 4 возможных значения? Я думал, что это имеет смысл, только когда появилось больше уникальных значений.

объяснить результаты:

+----+-------------+--------+--------+---------------+---------+---------+-----------------------+--------+-------------+ 
| id | select_type | table  | type   | possible_keys | key     | key_len | ref                   | rows   | Extra       |         
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+--------+-------------+ 
|  1 | SIMPLE      | table1 | ALL    | CurrentName   | NULL    | NULL    | NULL                  | 733190 | Using where | 
|  1 | SIMPLE      | table2 | eq_ref | PRIMARY       | PRIMARY | 4       | db.table1.CurrentName | 1      |             | 
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+--------+-------------+ 
2 rows in set (0.00 sec)

1 Ответ

2 голосов
/ 02 декабря 2010

Имеет ли значение размещение соединения?

Порядок, в котором они написаны, не имеет значения для ВНУТРЕННИХ СОЕДИНЕНИЙ.

Имеет ли значение порядок, в котором имеет значение пункт where, илиMySQL оптимизирует?

Нет.Письменный порядок в предложении WHERE не имеет значения для анализатора и оптимизатора запросов MySQL

Поможет ли и в моем случае индексирование?

Потенциально.Составной индекс type_status (Type, Status) для table1 может помочь, поскольку именно здесь ваше предложение WHERE может уменьшить начальное чтение строк.

Есть ли какое-либо преимущество JOINing в FROM по сравнению с добавлением 'table1.CurrentName = table2.id 'в предложении WHERE?

Для INNER JOINs не имеет значения, находится ли условие JOIN в предложении FROM или в предложении WHERE.

Я думал, что добавление индекса в table1.CurrentName может помочь, но теперь я думаю, что нет.Я изменил запрос, чтобы удалить ссылки на table2, и он все еще работал медленно.(см. 3b)

Индекс для table1.CurrentName не помог бы в запросе.

Похоже, что большая часть замедления может быть просто при чтении 800K записей, глядя наЗначения типа и статуса.

Это подтверждает мои мысли выше.Чтобы добавить составной индекс (возможно, это не очень хорошая вещь для онлайн), это было бы что-то вроде

ALTER TABLE table1 ADD INDEX type_status (Type, Status);

Я думал, что это имеет смысл, только когда есть больше уникальных значений.

Селективность определенно помогает, но высокая мощность не единственный подходящий контекст.

...