このページは機械翻訳したものです。
行コンストラクタを使用すると、複数の値を同時に比較できます。 たとえば、次の 2 つのステートメントは意味的に同等です:
Press CTRL+C to copySELECT * FROM t1 WHERE (column1,column2) = (1,1); SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
また、オプティマイザは両方の式を同じ方法で処理します。
行コンストラクタカラムがインデックスの接頭辞をカバーしていない場合、オプティマイザは使用可能なインデックスを使用する可能性が低くなります。 (c1, c2, c3)
で主キーを持つ次のテーブルについて考えてみます:
Press CTRL+C to copyCREATE TABLE t1 ( c1 INT, c2 INT, c3 INT, c4 CHAR(100), PRIMARY KEY(c1,c2,c3) );
このクエリーでは、WHERE
句はインデックス内のすべてのカラムを使用します。 ただし、行コンストラクタ自体はインデックス接頭辞をカバーしません。その結果、オプティマイザは c1
(key_len=4
、つまり c1
のサイズ) のみを使用します:
Press CTRL+C to copymysql> 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
このような場合、等価の非コンストラクタ式を使用して行コンストラクタ式をリライトすると、より完全なインデックスが使用される可能性があります。 指定されたクエリーについて、行コンストラクタおよび同等の非コンストラクタ式は次のとおりです:
Press CTRL+C to copy(c2,c3) > (1,1) c2 > 1 OR ((c2 = 1) AND (c3 > 1))
非コンストラクタ式を使用するようにクエリーをリライトすると、オプティマイザはインデックス内の 3 つのカラムすべて (key_len=12
) を使用します:
Press CTRL+C to copymysql> 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()
式に範囲アクセス方法を適用できます。 行コンストラクタ式の範囲最適化を参照してください。