Spec-Zone.ru › MySQL 9.2

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-9.2-en/where-optimization.html

Spec-Zone.ru

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