Spec-Zone .ru
спецификации, руководства, описания, API
|
Разработка является продолжающейся, таким образом, никакая подсказка по оптимизации не надежна в течение длительного срока. Следующий список обеспечивает некоторые интересные приемы, с которыми Вы могли бы хотеть играть:
Используйте пункты подзапроса, которые влияют на число или порядок строк в подзапросе. Например:
SELECT * FROM t1 WHERE t1.column1 IN (SELECT column1 FROM t2 ORDER BY column1);SELECT * FROM t1 WHERE t1.column1 IN (SELECT DISTINCT column1 FROM t2);SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 LIMIT 1);
Замените соединение подзапросом. Например, попробуйте это:
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN ( SELECT column1 FROM t2);
Вместо этого:
SELECT DISTINCT t1.column1 FROM t1, t2 WHERE t1.column1 = t2.column1;
Некоторые подзапросы могут быть преобразованы к соединениям для совместимости с более старыми версиями MySQL, которые не поддерживают подзапросы. Однако, в некоторых случаях, преобразование подзапроса к соединению может улучшить производительность. См. Раздел 13.2.10.11, "Переписывая Подзапросы как Соединения".
Переместите пункты снаружи во внутреннюю часть подзапрос. Например, используйте этот запрос:
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
Вместо этого запроса:
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
Для другого примера используйте этот запрос:
SELECT (SELECT column1 + 5 FROM t1) FROM t2;
Вместо этого запроса:
SELECT (SELECT column1 FROM t1) + 5 FROM t2;
Используйте подзапрос строки вместо связанного подзапроса. Например, используйте этот запрос:
SELECT * FROM t1 WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);
Вместо этого запроса:
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1 AND t2.column2=t1.column2);
Использовать NOT (a = ANY (...))
вместо a <> ALL (...)
.
Использовать x = ANY (
вместо table
containing (1,2)
)x=1 OR x=2
.
Использовать = ANY
вместо EXISTS
.
Для несвязанных подзапросов, которые всегда возвращают одну строку, IN
всегда медленнее чем =
. Например, используйте
этот запрос:
SELECT * FROM t1 WHERE t1.col_name
= (SELECT a FROM t2 WHERE b =some_const
);
Вместо этого запроса:
SELECT * FROM t1 WHERE t1.col_name
IN (SELECT a FROM t2 WHERE b =some_const
);
Эти приемы могли бы заставить программы идти быстрее или медленнее. Используя средства MySQL как BENCHMARK()
функция, можно понять о том, что помогает в Вашей собственной
ситуации. См. Раздел
12.14, "информационные Функции".
Некоторая оптимизация, которую делает сам MySQL:
MySQL выполняет несвязанные подзапросы только однажды. Использовать EXPLAIN
удостовериться, что данный подзапрос действительно является
некоррелированым.
Перезаписи MySQL IN
, ALL
,
ANY
, и SOME
подзапросы в попытке использовать
в своих интересах возможность, что столбцы списка выборки в подзапросе индексируются.
MySQL заменяет подзапросы следующей формы с функцией индексировать-поиска, который
EXPLAIN
описывает как специальный тип соединения (unique_subquery
или index_subquery
):
... IN (SELECTindexed_column
FROMsingle_table
...)
MySQL улучшает выражения следующей формы с включением выражения MIN()
или MAX()
, если NULL
значения или пустые
множества включаются:
value
{ALL|ANY|SOME} {> | < | >= | <=} (uncorrelated subquery
)
Например, это WHERE
пункт:
WHERE 5 > ALL (SELECT x FROM t)
мог бы быть обработан оптимизатором как это:
WHERE 5 > (SELECT MAX(x) FROM t)
См. также