2016-12-16 7 views
1

私はEXPLAINを使用して、インデックスにより、一部の照会のパフォーマンスを改善しようとしていたと私は、私は、クエリのEXPLAINrows columsのSHOW index FROM TableB;出力を使用するたびに例各SHOWインデックスの後にEXPLAINの出力が変化するのはなぜですか?

を変更気づい:

mysql> EXPLAIN Select A.id 
    From TableA A 
    Inner join TableB B 
     On A.address = B.address And A.code = B.code 
    Group by A.id 
    Having count(distinct B.id) = 1; 
+----+-------------+-------+--------+---------------+---------+---------+---------------------------------------+-------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref         | rows | Extra          | 
+----+-------------+-------+--------+---------------+---------+---------+---------------------------------------+-------+----------------------------------------------+ 
| 1 | SIMPLE  | B  | index | test_index | PRIMARY | 518  | NULL         | 10561 | Using index; Using temporary; Using filesort | 
| 1 | SIMPLE  | A  | eq_ref | PRIMARY  | PRIMARY | 514  | db.B.address,db.B.code    |  1 |            | 
+----+-------------+-------+--------+---------------+---------+---------+---------------------------------------+-------+----------------------------------------------+ 
2 rows in set (0.00 sec) 

mysql> show index from TableB; 
+-----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table  | Non_unique | Key_name  | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+-----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| TableB |   0 | PRIMARY  |   1 | id   | A   |   7 |  NULL | NULL |  | BTREE  |   | 
| TableB |   0 | PRIMARY  |   2 | address  | A   |   21 |  NULL | NULL |  | BTREE  |   | 
| TableB |   0 | PRIMARY  |   3 | code  | A   |  10402 |  NULL | NULL |  | BTREE  |   | 
| TableB |   1 | test_index |   1 | address  | A   |   1 |  NULL | NULL |  | BTREE  |   | 
| TableB |   1 | test_index |   2 | code  | A   |  10402 |  NULL | NULL |  | BTREE  |   | 
| TableB |   1 | test_index |   3 | id   | A   |  10402 |  NULL | NULL |  | BTREE  |   | 
+-----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
6 rows in set (0.03 sec) 

と...

mysql> EXPLAIN Select A.id 
     From TableA A 
     Inner join TableB B 
      On A.address = B.address And A.code = B.code Group by A.id 
     Having count(distinct B.id) = 1; 
+----+-------------+-------+--------+---------------+---------+---------+---------------------------------------+-------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref         | rows | Extra          | 
+----+-------------+-------+--------+---------------+---------+---------+---------------------------------------+-------+----------------------------------------------+ 
| 1 | SIMPLE  | B  | index | test_index | PRIMARY | 518  | NULL         | 9800 | Using index; Using temporary; Using filesort | 
| 1 | SIMPLE  | A  | eq_ref | PRIMARY  | PRIMARY | 514  | db.B.address,db.B.code    |  1 |            | 
+----+-------------+-------+--------+---------------+---------+---------+---------------------------------------+-------+----------------------------------------------+ 
2 rows in set (0.00 sec) 

どうしてですか?

+0

「持続的な統計情報」が利用可能になったときに5.6.6より古いバージョンを使用しているようです。 –

答えて

3

rowsの列は概算としてのみ使用してください。それは正確な数字ではありません。

これは、クエリ中に検査される行数の統計的見積もりに基づいています。実際の行数は、実際にクエリを実行するまで認識できません。

統計情報は、テーブルから定期的に読み取られたサンプルに基づいています。これらのサンプルは、たとえばANALYZE TABLEまたは特定のINFORMATION_SCHEMAクエリ、または特定のSHOWステートメントを実行した後で、時折再読み込みされます。

+0

'EXPLAIN EXTENDED'はこれに何らかの影響を与えますか? – Rahul

+0

いいえ、EXPLAIN EXTENDEDは、EXPLAIN出力にもう1つの情報列を追加して、クエリによってフィルタリングされる行の推定割合を表示することを意味します。このオプションは、MySQL 5.7では不要です。なぜなら、そのカラムは現在デフォルトでインクルードされているからです。 –

+0

偉大な...応答ビルのおかげで。 – Rahul

0

私は統計情報の20%のばらつきは大したことではありません。多くの状況では、グラフが上向きの放物線のようなものだと考えて、最小点のどちら側にいるかを知る必要があります。オプティマイザが複雑になる複雑なクエリでは、MariaDB 10.0/10.1のヒストグラムなどの単純な統計情報以上のものが必要です。 (私はそれが十分に進歩しているかどうかを言うのに十分な経験はありません)

あなたの特定のクエリは、統計にかかわらず、たぶん1つの方法で実行されるでしょう。複雑なクエリの例は、JOINWHERE句の各テーブルをフィルタリングすることです。オプティマイザは、どのテーブルで開始するかを決定する必要があります。別のケースでは、WHEREORDER BYという単一のテーブルがあり、両方を単一のインデックスで処理することはできません。インデックスを使用してフィルタリングする必要がありますが、ソートする必要があります。またはORDER BYのインデックスを使用する必要がありますが、その場でフィルタリングする必要がありますか?

関連する問題