web-dev-qa-db-ja.com

mysqlの説明で行数が非常に多い理由

私はmysqlを使用しています、これはクエリです-

mysql> select count(*) from payments as Payment WHERE `Payment`.`fordate` BETWEEN '2015-11-28 00:00:00' AND '2015-12-31 23:59:59';
+----------+
| count(*) |
+----------+
|   187216 |
+----------+
1 row in set (0.16 sec)

mysql> explain select count(*) from payments as Payment WHERE `Payment`.`fordate` BETWEEN '2015-11-28 00:00:00' AND '2015-12-31 23:59:59';
+----+-------------+---------+-------+-----------------+-----------------+---------+------+--------+--------------------------+
| id | select_type | table   | type  | possible_keys   | key             | key_len | ref  | rows   | Extra                    |
+----+-------------+---------+-------+-----------------+-----------------+---------+------+--------+--------------------------+
|  1 | SIMPLE      | Payment | range | pafordate_index | pafordate_index | 5       | NULL | 379894 | Using where; Using index |
+----+-------------+---------+-------+-----------------+-----------------+---------+------+--------+--------------------------+
1 row in set (0.04 sec)

explain行数が多すぎるのはなぜですか、実際には少ないのです。

3

テーブルはInnoDBですか?そのため、インデックス統計は "index dives" によって収集され、定義上不正確です。

EXPLAINは実際にはクエリを実行していませんが、見積もりを使用して、不正確な数値を表示するように計画しています。

重要なことは、それが実際と同じorderで数値を保持する場合(これは、あなたの場合はdoubleである)、うまく機能することです。ほとんどの場合に十分です。

正確な数値を維持するのは面倒であり、トランザクション環境では実際には不可能です。

3
jkavalik

クエリで_Payment.fordate_がインデックス付けされていない場合、オプティマイザはテーブル全体を検索することを期待しています。 count(*)値のみを返すため、1行だけが返されます。列を追加して_group by_句を追加すると、返される行の予想数が変わる可能性があります。

Explain計画は、データベースから入手可能な統計に基づいて推定データを使用します。このデータは通常間違っていますが、妥当な計画を立てるのに十分近いです。通常、実際の値ではなく、桁数がカウントされます。

Between句のカウントを作成する際のエラーが原因で、値が2倍ずれている可能性があります。

1
BillThor