Documentation Home
MySQL 9.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 41.2Mb
PDF (A4) - 41.3Mb
Man Pages (TGZ) - 262.8Kb
Man Pages (Zip) - 368.8Kb
Info (Gzip) - 4.1Mb
Info (Zip) - 4.1Mb


MySQL 9.4 Reference Manual  / ...  / Optimization  / Optimizing SQL Statements  / Optimizing SELECT Statements  /  Row Constructor Expression Optimization

10.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):

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

In this query, theWHERE clause uses all columns in the index. However, the row constructor itself does not cover an index prefix, with the result that the optimizer uses onlyc1 (key_len=4, the size ofc1):

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: refpossible_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):

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: rangepossible_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 withAND/OR expressions. Use one or the other.

Under certain conditions, the optimizer can apply the range access method toIN() expressions that have row constructor arguments. SeeRange Optimization of Row Constructor Expressions.