Spec-Zone.ru › MySQL 8.4

10.2.1.1 Оптимизация условия WHERE

В этом разделе обсуждаются оптимизации, которые можно применить к обработке условий WHERE. В примерах используются операторы SELECT, но те же оптимизации применяются к условиям WHERE в операторах DELETE и UPDATE.

Примечание

Поскольку работа над оптимизатором MySQL продолжается, не все оптимизации, выполняемые MySQL, документированы здесь.

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

  • Удаление ненужных скобок:

       ((a AND b) AND c OR (((a AND b) AND (c AND d))))
    -> (a AND b AND c) OR (a AND b AND c AND d)
    
  • Сворачивание констант:

       (a<b AND b=c) AND a=5
    -> b>5 AND b=c AND a=5
    
  • Удаление условий с константами:

       (b>=5 AND b=5) OR (b=6 AND 5=5) OR (b=7 AND 5=6)
    -> b=5 OR b=6
    

    Это происходит во время подготовки, а не во время фазы оптимизации, что помогает в упрощении объединений. Для получения дополнительной информации и примеров см. Раздел 10.2.1.9, «Оптимизация внешних объединений».

  • Постоянные выражения, используемые индексами, вычисляются только один раз.

  • Сравнения столбцов числовых типов с константными значениями проверяются и сворачиваются или удаляются для недопустимых или выходящих за пределы значений:

    # CREATE TABLE t (c TINYINT UNSIGNED NOT NULL);
      SELECT * FROM t WHERE c < 256;
    -≫ SELECT * FROM t WHERE 1;
    

    Дополнительную информацию см. в разделе 10.2.1.14, «Оптимизация сворачивания констант».

  • COUNT(*) по одному таблице без WHERE извлекается непосредственно из информации о таблице для таблиц MyISAM и MEMORY. Это также делается для любого выражения NOT NULL при использовании только с одной таблицей.

  • Раннее обнаружение недопустимых константных выражений. MySQL быстро обнаруживает, что некоторые операторы SELECT невозможны и не возвращают строк.

  • HAVING объединяется с WHERE, если вы не используете GROUP BY или агрегатные функции (COUNT(), MIN() и т. д.).

  • Для каждой таблицы в объединении строится более простое WHERE, чтобы получить быстрое WHERE вычисление для таблицы и также пропустить строки как можно скорее.

  • Все постоянные таблицы считываются перед любыми другими таблицами в запросе. Постоянная таблица — это любая из следующих:

    • Пустая таблица или таблица с одной строкой.

    • Таблица, которая используется с условием WHERE по индексу PRIMARY KEY или UNIQUE, где все части индекса сравниваются с константными выражениями и определены как NOT NULL.

    Все следующие таблицы используются как постоянные:

    SELECT * FROM t WHERE primary_key=1;
    SELECT * FROM t1,t2
      WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
    
  • Лучшая комбинация объединений для объединения таблиц находится путем перебора всех возможностей. Если все столбцы в условиях ORDER BY и GROUP BY происходят из одной таблицы, эта таблица предпочтительнее при объединении.

  • Если есть условие ORDER BY и другое условие GROUP BY, или если ORDER BY или GROUP BY содержат столбцы из таблиц, отличных от первой таблицы в очереди объединения, создается временная таблица.

  • Если используется модификатор SQL_SMALL_RESULT, MySQL использует временную таблицу в памяти.

  • Каждый индекс таблицы запрашивается, и используется лучший индекс, если оптимизатор не считает, что использование сканирования таблицы более эффективно. В одном случае сканирование использовалось на основе того, охватывал ли лучший индекс более 30% таблицы, но фиксированный процент больше не определяет выбор между использованием индекса или сканированием. Оптимизатор теперь более сложный и основывает свою оценку на дополнительных факторах, таких как размер таблицы, количество строк и размер блока ввода-вывода.

  • В некоторых случаях MySQL может считывать строки из индекса, даже не обращаясь к файлу данных. Если все столбцы, используемые из индекса, являются числовыми, для решения запроса используется только дерево индекса.

  • Перед выводом каждой строки те, которые не соответствуют условию HAVING, пропускаются.

Некоторые примеры запросов, которые очень быстрые:

SELECT COUNT(*) FROM tbl_name;

SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;

SELECT MAX(key_part2) FROM tbl_name
  WHERE key_part1=constant;

SELECT ... FROM tbl_name
  ORDER BY key_part1,key_part2,... LIMIT 10;

SELECT ... FROM tbl_name
  ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;

MySQL решает следующие запросы, используя только дерево индекса, предполагая, что индексированные столбцы являются числовыми:

SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;

SELECT COUNT(*) FROM tbl_name
  WHERE key_part1=val1 AND key_part2=val2;

SELECT MAX(key_part2) FROM tbl_name GROUP BY key_part1;

Следующие запросы используют индексацию для получения строк в отсортированном порядке без отдельного этапа сортировки:

SELECT ... FROM tbl_name
  ORDER BY key_part1,key_part2,... ;

SELECT ... FROM tbl_name
  ORDER BY key_part1 DESC, key_part2 DESC, ... ;

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/where-optimization.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API