Spec-Zone.ru › MySQL 5.7

13.2.10.10 Оптимизация подзапросов

Разработка продолжается, поэтому никакие советы по оптимизации не гарантируют долговременной эффективности. В следующем списке приведены некоторые интересные приёмы, которые можно попробовать. См. также Раздел 8.2.2, «Оптимизация подзапросов, производных таблиц и ссылок на представления».

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

    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.15, «Функции информации».

Некоторые оптимизации, которые выполняет сам MySQL:

  • MySQL выполняет некоррелированные подзапросы только один раз. Используйте EXPLAIN, чтобы убедиться, что данный подзапрос действительно некоррелированный.

  • MySQL переписывает IN, ALL, ANY и SOME подзапросы, пытаясь воспользоваться возможностью индексирования столбцов списка выбора в подзапросе.

  • MySQL заменяет подзапросы следующей формы функцией поиска по индексу, которую EXPLAIN описывает как особый тип соединения (unique_subquery или index_subquery):

    ... IN (SELECT indexed_column FROM single_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)
    

См. также MySQL Internals: How MySQL Transforms Subqueries.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/optimizing-subqueries.html

Spec-Zone.ru

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