Tips.7 続)本当にCOUNT(*)は遅いのか?COUNT(列名)は速いのか?~実行計画を確認~

Oracle, パフォーマンスcount, Oracle, PL/SQL, SQL, パフォーマンス

前回は、COUNT(*)が必ずしも遅いわけではないことはおわかり頂けたと思います。
もう一つ検証したいポイントがあります。
よく言われている「COUNT(*)は全表走査(FULLSCAN)になるので遅い」という点です。

試しに前回実行した次のSQLの実行計画を取得してみましょう。
前回と同様に、COUNT(*)を取得するだけのシンプルなSQLで確認してみます。

SELECT COUNT(*) FROM pt_count_test;
COUNT(*)で抽出条件もない場合の実行計画

続いてCOUNT(PK列)の場合。
SELECT COUNT(pkid) FROM pt_count_test;
COUNT(PK列)で抽出条件もない場合の実行計画

いずれも同じ実行計画になりました。
COUNT(*)を使ったからと言ってFULLSCANになるわけではないようです。

これまではWHERE句なしのSQLばかりでしたが、実行計画はWHERE句で決まるもの。
WHERE句を入れてみましょう。

SELECT COUNT(*) FROM pt_count_test WHERE LENGTH(val2) > 500;
COUNT(*)でWHERE句が入っている場合(INDEXなし)

SELECT COUNT(pkid) FROM pt_count_test WHERE LENGTH(val3) > 500;
COUNT(PK列)でWHERE句が入っている場合(INDEXなし)

やはり抽出条件が同じであればCOUNT(*)かCOUNT(列名)かで、実行計画が変わることは無いようです。

次は抽出条件にプライマリキー項目を使用してみます。

SELECT COUNT(*) FROM pt_count_test WHERE pkid >=0;
COUNT(*)でWHERE句が入っている場合(INDEX使用)

SELECT COUNT(pkid) FROM pt_count_test WHERE pkid >=0;
COUNT(PK列)でWHERE句が入っている場合(INDEX使用)

やはり変わらないですね。

ということですので、安心してCOUNT(*)をご使用ください。