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
):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
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.请参阅行构造函数表达式的范围优化。