このクエリ:select count(*) from planner_event
実行に非常に長い時間がかかります-とても長いので、終了する前にそれをgaveめて殺しました。ただし、実行するexplain select count(*) from planner_event
と、出力に列数(14m)の列が表示されます。
Explainが行数を即座に取得できるのに、count(*)の実行に時間がかかるのはなぜですか?
このクエリ:select count(*) from planner_event
実行に非常に長い時間がかかります-とても長いので、終了する前にそれをgaveめて殺しました。ただし、実行するexplain select count(*) from planner_event
と、出力に列数(14m)の列が表示されます。
Explainが行数を即座に取得できるのに、count(*)の実行に時間がかかるのはなぜですか?
回答:
Explainは、以前に収集された統計(クエリオプティマイザーが使用)を使用しています。実行すると、select count(*)
すべてのデータ・ブロックを読み込みます。
推定行数を取得する安価な方法を次に示します。
select TABLE_ROWS
FROM INFORMATION_SCHEMA.TABLES
where TABLE_NAME='planner_event';
行ったとしてもselect count(id)
、セカンダリインデックスがオンになっていない限り、非常に長い時間がかかる場合がありますid
(id
プライマリキーも想定)。すべてのデータ(行データを含む)はBツリーインデックスに格納されるため、aの実行select count(PK_COLUMN)
は依然としてかなりの量のIOです(すべてのデータページを読み取る必要があります)。PKフィールドにセカンダリインデックスがある場合、カウントを実行するために実行するIOが少なくなります。
EXPLAIN
与えます。
AND TABLE_SCHEMA='my_database'
別のデータベースに同じ名前のテーブルがある場合、クエリが欠落しています。そうでない場合、複数の結果が返されます。
Explainは、オプティマイザーの事柄を推定するために使用されるいくつかの「統計」から数値を取得します。その数は正確とはほど遠い場合があります。正確な値よりも2倍(高いまたは低い)を超えることがあります。
COUNT(*)
InnoDBテーブルでを実行すると、テーブルをスキャンして、他の接続によって挿入/削除されているがまだ「コミット」されていないビジーなレコードをカウントしないようにする必要があります。実際には、(テーブルを含むPRIMARY KEY
)テーブル全体ではなく、何らかのインデックスでフルスキャンを実行するだけで十分です。
RAMはどれくらいありますか?の価値はinnodb_buffer_pool_size
何ですか?RAMの約70%である場合に役立ちます。