Documentation Home
MySQL 8.0 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 36.1Mb
PDF (A4) - 36.2Mb


このページは機械翻訳したものです。

8.2.1.22 行コンストラクタ式の最適化

行コンストラクタを使用すると、複数の値を同時に比較できます。 たとえば、次の 2 つのステートメントは意味的に同等です:

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

非コンストラクタ式を使用するようにクエリーをリライトすると、オプティマイザはインデックス内の 3 つのカラムすべて (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

したがって、より適切な結果を得るには、行コンストラクタとAND/OR 式を混在させないでください。 一方を使用してください。

特定の条件下では、オプティマイザは行コンストラクタ引数を持つIN() 式に範囲アクセス方法を適用できます。行コンストラクタ式の範囲最適化を参照してください。