8.2.1.22 Row Constructor Expression Optimization行构造函数表达式优化

Row constructors permit simultaneous comparisons of multiple values. 行构造函数允许同时比较多个值。For example, these two statements are semantically equivalent:例如,这两个语句在语义上是等价的:

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

In addition, the optimizer handles both expressions the same way.此外,优化器以相同的方式处理这两个表达式。

The optimizer is less likely to use available indexes if the row constructor columns do not cover the prefix of an index. 如果行构造函数列不包含索引的前缀,则优化器不太可能使用可用索引。Consider the following table, which has a primary key on (c1, c2, c3):考虑下表,它在(c1, c2, c3)上有主键:

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

In this query, the WHERE clause uses all columns in the index. 在此查询中,WHERE子句使用索引中的所有列。However, the row constructor itself does not cover an index prefix, with the result that the optimizer uses only c1 (key_len=4, the size of c1):但是,行构造函数本身不包含索引前缀,因此优化器只使用c1key_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

In such cases, rewriting the row constructor expression using an equivalent nonconstructor expression may result in more complete index use. 在这种情况下,使用等效的非构造函数表达式重写行构造函数表达式可能会导致更完整的索引使用。For the given query, the row constructor and equivalent nonconstructor expressions are:对于给定的查询,行构造函数和等效的非构造函数表达式为:

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

Rewriting the query to use the nonconstructor expression results in the optimizer using all three columns in the index (key_len=12):重写查询以使用非结构化表达式将导致优化器使用索引中的所有三列(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

Thus, for better results, avoid mixing row constructors with AND/OR expressions. 因此,为了获得更好的结果,请避免将行构造函数与AND/OR表达式混合使用。Use one or the other.请使用一个或另一个。

Under certain conditions, the optimizer can apply the range access method to IN() expressions that have row constructor arguments. 在某些条件下,优化器可以将范围访问方法应用于具有行构造函数参数的IN()表达式。See Range Optimization of Row Constructor Expressions.请参阅行构造函数表达式的范围优化