Spec-Zone.ru › MySQL 9.2

10.2.1.22 Оптимизация выражений конструктора строк

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

SELECT * FROM t1 WHERE (column1,column2) = (1,1);
SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;

Кроме того, оптимизатор обрабатывает оба выражения одинаково.

Оптимизатор менее склонен использовать доступные индексы, если столбцы конструктора строк не охватывают префикс индекса. Рассмотрим следующую таблицу, которая имеет первичный ключ по (c1, c2, c3):

CREATE TABLE t1 (
  c1 INT, c2 INT, c3 INT, c4 CHAR(100),
  PRIMARY KEY(c1,c2,c3)
);

В этом запросе клаузула WHERE использует все столбцы в индексе. Однако сам конструктор строк не охватывает префикс индекса, в результате чего оптимизатор использует только c1 (key_len=4, размер c1):

mysql> EXPLAIN SELECT * FROM t1
       WHERE c1=1 AND (c2,c3) > (1,1)\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
   partitions: NULL
         type: ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: const
         rows: 3
     filtered: 100.00
        Extra: Using where

В таких случаях переписывание выражения конструктора строк с использованием эквивалентного выражения без конструктора может привести к более полному использованию индекса. Для данного запроса выражения конструктора строк и эквивалентные выражения без конструктора:

(c2,c3) > (1,1)
c2 > 1 OR ((c2 = 1) AND (c3 > 1))

Переписывание запроса с использованием выражения без конструктора приводит к тому, что оптимизатор использует все три столбца в индексе (key_len=12):

mysql> EXPLAIN SELECT * FROM t1
       WHERE c1 = 1 AND (c2 > 1 OR ((c2 = 1) AND (c3 > 1)))\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
   partitions: NULL
         type: range
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 12
          ref: NULL
         rows: 3
     filtered: 100.00
        Extra: Using where

Таким образом, для достижения лучших результатов следует избегать смешивания конструкторов строк с выражениями AND/OR. Используйте один или другой.

В определенных условиях оптимизатор может применить метод диапазонного доступа к выражениям IN() с аргументами конструктора строк. См. Оптимизацию диапазонов выражений конструктора строк.

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

Spec-Zone.ru

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