2016-07-27 3 views
0

これはMySQL 5.7のInnoDB用です。MySQL - 関連するカスケードクエリのセットの最適インデックス

SELECT DISTINCT A, COUNT(*) FROM MYTABLE 
    WHERE D IN ? AND A > ? 
    GROUP BY A ORDER BY A LIMIT 100 

SELECT DISTINCT B, COUNT(*) FROM MYTABLE 
    WHERE A = ? AND D IN ? AND B > ? 
    GROUP BY B ORDER BY B LIMIT 100 

SELECT DISTINCT C, COUNT(*) FROM MYTABLE 
    WHERE A = ? AND B = ? AND D IN ? AND C > ? 
    GROUP BY C ORDER BY C LIMIT 100 

SELECT E, F, G, H FROM MYTABLE 
    WHERE A = ? AND B = ? AND C = ? AND D IN ? AND ID > ? 
    ORDER BY ID LIMIT 100 

すべてのクエリは、各によってプルーニングするインデックス(ES)のいずれかを使用することができインデックス(ES)などの最小限のセットを何ですか:

私は4つの関連のカスケードクエリのセットを持っていますWHERE句を使用して、ORDER BYをスピードアップするためにそれらを使用しますか?私は複合インデックスについて理解するものから

、私は必要があります

CREATE INDEX INDEX01 ON MYTABLE (D, A) 

CREATE INDEX INDEX02 ON MYTABLE (A, D, B) 

CREATE INDEX INDEX03 ON MYTABLE (A, B, D, C) 

CREATE INDEX INDEX04 ON MYTABLE (A, B, C, D) 

これは正しいです(IDが主キー列ですか)?

私は、WHERE句を並べ替えた場合、私はおそらくただ一つの複合指数で間に合わせることができます図:

SELECT DISTINCT A, COUNT(*) FROM MYTABLE 
    WHERE D IN ? AND A > ? 
    GROUP BY A ORDER BY A LIMIT 100 

SELECT DISTINCT B, COUNT(*) FROM MYTABLE 
    WHERE D IN ? AND A = ? AND B > ? 
    GROUP BY B ORDER BY B LIMIT 100 

SELECT DISTINCT C, COUNT(*) FROM MYTABLE 
    WHERE D IN ? AND A = ? AND B = ? AND C > ? 
    GROUP BY C ORDER BY C LIMIT 100 

SELECT E, F, G, H FROM MYTABLE 
    WHERE D IN ? AND A = ? AND B = ? AND C = ? AND ID > ? 
    ORDER BY ID LIMIT 100 

その後、私はちょうど必要があります:

CREATE INDEX INDEX01 ON MYTABLE (D, A, B, C) 

が正しいということですか?

しかし、WHERE句をこのように並べると最適ではないと思います。常に節があり、最後の2として「IN」操作と「>」の操作を置くしようとしている理由:

  1. MySQLは「IN」のためのより多くの作業を行う必要があります(複数の値と比較) "="と比較して、おそらく(私のデータセットと私がフィルタリングしているもののために)、この節によって少ない行が刈り込まれます。

  2. ">"操作は、主に改行の目的に使用されます。すなわち、場合によっては、この節のために枝刈りがほとんどまたは全くない。

私の理解は正しいですか?

+0

それは現実世界の健康システムのためにあなたのデータ型に依存します。それらは薄くなっているか、またはロードされていますか?varchar(255) – Drew

+0

オプティマイザについては[this](http://stackoverflow.com/a/38002986)を、 – Drew

答えて

1

do do同じDISTINCTGROUP BYの両方を同じクエリで実行します。集計(COUNT)のため、おそらくGROUP BYが必要なので、DISTINCTを投げてください。 GROUP BY x ORDER BY x LIMIT 100については

、以下かもしれヘルプ:

INDEX(x) -- or INDEX(x, ...) 

だから、念のため、ということがあります。これにより、オプティマイザのインデックスを使用することを選択した場合、を参照する代わりにGROUP BY + ORDER BY + LIMITを処理することを意味します。それはWHEREを使用することを決定した場合は、...

WHERE D IN ? AND A > ? 
INDEX(D, A) 

は(「MRR」)を飛び越すD'sおよびAさんをスキャンし、それがどのGROUP BYまたはORDER BYを消費することはできません。

WHERE A = ? AND D IN ? AND B > ? 
INDEX(A, D, B) 

「=」を最初にインデックスに入れます。残りのロジックは上記のとおりです。

WHERE A = ? AND B = ? AND D IN ? AND C > ? 
INDEX(A, B, D, C) or INDEX(B, A, D, C) 

(同じロジック)

WHERE A = ? AND B = ? AND C = ? AND D IN ? AND ID > ? 
INDEX(A,B,C, -- in any order, then 
     D, ID) -- at end, in this order. 

ので、4文の集合のために、私は与えられた順序で、4つのまたは5のインデックスをお勧めします。ボーナスとして

INDEX(D, A) 
INDEX(A, D, B) 
INDEX(B, A, D, C) -- I picked that one to get one starting with B 
INDEX(c, B, A, D, ID) 
INDEX(ID) -- but don't add if you already have `PRIMARY KEY(ID)` 

、これらのインデックスのうち最初の3つのインデックスには「カバー」インデックスがあり、これにより特別なボーナスが得られます。最後のSELECTには、 "カバーする" 9桁のインデックスが必要です。それは多すぎます。

WHEREの中のANDのものの順序は違いはありません。だから、私はあなたの質問の残りの部分を無視することができると思う。

(警告:「最高の」一連の索引ので、約5.6前に、飛び越すは、存在しなかったが、何か他のものになります。)

関連する問題