Spec-Zone.ru › MySQL 5.7

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

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

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-5.7-en/row-constructor-optimization.html

Spec-Zone.ru

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