Точно ли MySQL выполняет поиск, если критерии, очевидно, соответствуют всем случаям в столбце

#mysql #performance

#mysql #Производительность

Вопрос:

Мне было интересно, нужно ли мне вводить условный оператор для удаления критерия, если этот критерий таков, что он охватывает все возможные значения в столбце. Пример выглядит следующим образом:

 SELECT product FROM Table where condition = 'condition' AND class <= 255;
 

Допустим, столбец класса имеет значение TINYINT unsigned NOT NULL DEFAULT 0 . Будет ли MySQL по-прежнему точно сканировать столбец, чтобы проверить, если class <= 255 ? Как приведенный выше запрос выполняется по отношению к этому заявлению ниже, предполагая, что у меня 10 миллионов строк?

 SELECT product FROM Table where condition = 'condition';
 

После некоторого тестирования в моей собственной базе данных я понимаю, что MySQL точно сканирует весь столбец, хотя очевидно, что поиск вернет весь столбец. Разница в производительности для моего случая составляет порядка нескольких секунд. Между двумя планами запросов нет разницы.

Я хотел бы дополнительно добавить, что сканирование также будет выполнено для запроса ниже:

 SELECT product FROM Table where condition = 'condition' AND class >= 0;
 

Я не уверен, почему такой запрос не оптимизирован MySQL. Я надеюсь, что кто-нибудь сможет просветить меня ответом. Спасибо 🙂

Комментарии:

1. tinyint(1) совпадает с tinyint и может хранить значения от -128 до 127: dev.mysql.com/doc/refman/5.0/en/numeric-types.html

2. В консоли MySQL запустите EXPLAIN SELECT product FROM Table where condition = 'condition' AND class <= 9; и EXPLAIN SELECT product FROM Table where condition = 'condition'; и посмотрите, получите ли вы другой план выполнения.

3. @ michael, я вижу, что вы правы в этом. Позвольте мне пересмотреть мой вопрос, чтобы сделать его более применимым.

4. @ Asaph, план запроса точно такой же.

5. Столбец должен быть NOT NULL for class <= 255 , чтобы гарантированно совпадать со всеми строками. Кстати, я тестировал в SQL Server, и это тоже не обнаруживает этого, если в столбец не добавлено явно избыточное ограничение проверки. CREATE TABLE #T(X TINYINT NOT NULL PRIMARY KEY,Y TINYINT NOT NULL CHECK (Y BETWEEN 0 AND 255),Z INT UNIQUE);SELECT Z FROM #T WHERE Y <= 255

Ответ №1:

MySQL не устраняет бессмысленные критерии, например, class >= 0 для столбца целых чисел без знака.

Вот список всех where оптимизаций, которые выполняет MySQL:
http://dev.mysql.com/doc/refman/5.0/en/where-optimizations.html

Однако MySQL обнаруживает, что class >= 0 будет много обращений, и не будет пытаться использовать индекс.
Что касается condition = 'condition' предложения, использует ли он индекс, определяется мощностью этого столбца.
Более чем, скажем, 20% строк соответствуют условию, будет выполнено полное сканирование таблицы, если не будет использоваться индекс.

Если оба критерия могут использовать индекс, будет использоваться индекс с наибольшей ожидаемой мощностью.
MySQL будет использовать только один индекс для каждой таблицы для каждого подвыбора / объединения.

MySQL не исключает критерии where из оценки, но выполняет логическую оценку короткого замыкания для AND и OR .
Таким образом, это позволит избежать полного сканирования таблицы, если он может использовать индекс on condition .

Если MySQL выполняет полное сканирование таблицы
Ему нужно будет выполнить другой тест class только для тех строк, которые совпадают condition , но не для всех строк.
Оптимизатор запросов будет оценивать предложения в порядке, который дает самые быстрые результаты, поэтому он должен condition сначала оценить (потому что это = сравнение), а затем class (потому что его a> тест с низким значением).

Комментарии:

1. как обсуждалось с Avi, независимо от того, включен индекс или нет condition , MySQL все равно выполняет проверку class столбца. С индексом этот процесс ускоряется. На эту часть вопроса был дан ответ. Вторая часть о том, почему такая оптимизация не была выполнена, отсутствует.