Spec-Zone .ru
спецификации, руководства, описания, API
|
Этот раздел обсуждает оптимизацию, которая может быть сделана для того, чтобы обработать 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
Константные выражения, используемые, индексируют, оцениваются только однажды.
COUNT(*)
на единственной таблице без a WHERE
получается непосредственно от информации о таблице для MyISAM
и MEMORY
таблицы. Это также делается для любого NOT
NULL
выражение когда использующийся только с одной таблицей.
Раннее обнаружение недопустимых константных выражений. MySQL быстро обнаруживает
что некоторые SELECT
операторы невозможны, и не возвращает строк.
HAVING
объединяется с WHERE
если Вы не используете GROUP BY
или
агрегатные функции (COUNT()
, MIN()
, и так далее).
Для каждой таблицы в соединении, более простом WHERE
создается, чтобы получить быстрое WHERE
оценка для таблицы и также
пропускать строки как можно скорее.
Все постоянные таблицы читаются сначала перед любыми другими таблицами в запросе. Постоянная таблица является любым следующим:
Пустая таблица или таблица с одной строкой.
Таблица, которая используется с a WHERE
пункт на a PRIMARY KEY
или a UNIQUE
индексируйте, где все индексируют части, по сравнению
с константными выражениями и определяются как NOT NULL
.
Все следующие таблицы используются в качестве постоянных таблиц:
SELECT * FROM t WHEREprimary_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(*) FROMtbl_name
;SELECT MIN(key_part1
),MAX(key_part1
) FROMtbl_name
;SELECT MAX(key_part2
) FROMtbl_name
WHEREkey_part1
=constant
;SELECT ... FROMtbl_name
ORDER BYkey_part1
,key_part2
,... LIMIT 10;SELECT ... FROMtbl_name
ORDER BYkey_part1
DESC,key_part2
DESC, ... LIMIT 10;
MySQL разрешает следующие запросы, используя только индексировать дерево, предполагая, что индексированные столбцы являются числовыми:
SELECTkey_part1
,key_part2
FROMtbl_name
WHEREkey_part1
=val
;SELECT COUNT(*) FROMtbl_name
WHEREkey_part1
=val1
ANDkey_part2
=val2
;SELECTkey_part2
FROMtbl_name
GROUP BYkey_part1
;
Следующая индексация использования запросов, чтобы получить строки в сортированном порядке без отдельной передачи сортировки:
SELECT ... FROMtbl_name
ORDER BYkey_part1
,key_part2
,... ;SELECT ... FROMtbl_name
ORDER BYkey_part1
DESC,key_part2
DESC, ... ;