SELECT文でテーブルの件数を数える時にCOUNT(*)とCOUNT(1)どちらが処理が速いのか?
COUNTするときは「*」で記述するより「1」で記載したほうが速いよと会社の先輩に教えてもらったのですが、ネットで調べてもあまり「1」にしたほうが処理速度が速くなるって結果がなかったので自分で検証することにします\(^o^)/
COUNT文の構文
以前の記事に書いてるのでそちらを参照。
検証した環境
OS | Windows7 |
DB | Oracle Database Express Edition 11g |
検証内容(1) INDEXなしの場合COUNT(*)とCOUNT(1)どちらが処理速度が速いのか?
検証用のテーブルとデータ
今回はINDEXを作成してない状態の以下のテーブルで検証してみることにします。
CREATE TABLE TEST_TABLE ( id VARCHAR2(10) , name VARCHAR2(50) );
DESC TEST_TABLE; 名前 NULL? 型 --------------------- -------- --------------------- ID VARCHAR2(10) NAME VARCHAR2(50)
テストデータは、以下のPL/SQLで300万件データを作成して検証に使います。
BEGIN FOR I IN 1..3000000 LOOP INSERT INTO TEST_TABLE VALUES(I, RPAD(TO_CHAR(I),50,'A')); END LOOP; COMMIT; END; /
処理速度を測る前にキャッシュを削除します。
キャッシュ上にデータがキャッシュされていると、SQL実行時にハードディスクへ読みに行く必要が無いためレスポンスが速くなる傾向があります。
キャッシュを削除することにより環境的に同条件の状態で検証を行います。
--共有プールの削除 ALTER SYSTEM FLUSH SHARED_POOL; --データベースバッファキャッシュの削除 ALTER SYSTEM FLUSH BUFFER_CACHE;
COUNT(*)の処理速度
SELECT COUNT(*) FROM TEST_TABLE; 経過: 00:00:05.51
COUNT(*)の実行計画
実行計画 ---------------------------------------------------------- Plan hash value: 711311523 ------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 3 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS FULL| TEST_TABLE | 1 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------- 統計 ---------------------------------------------------------- 39 recursive calls 0 db block gets 68923 consistent gets 68894 physical reads 0 redo size 549 bytes sent via SQL*Net to client 523 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 5 sorts (memory) 0 sorts (disk) 1 rows processed
COUNT(1)の処理速度
SELECT COUNT(1) FROM TEST_TABLE; 経過: 00:00:05.68
COUNT(1)の実行計画
実行計画 ---------------------------------------------------------- Plan hash value: 711311523 ------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 3 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS FULL| TEST_TABLE | 1 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------- 統計 ---------------------------------------------------------- 39 recursive calls 0 db block gets 68923 consistent gets 68894 physical reads 0 redo size 549 bytes sent via SQL*Net to client 523 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 5 sorts (memory) 0 sorts (disk) 1 rows processed
結果・考察
処理時間は、誤差レベルですね。3回ほど試しましたがほぼ変わらない結果でした。
処理コストにいったては全く一緒ですね\(^o^)/
今回の検証結果では、COUNT(*)とCOUNT(1)の処理時間はほぼ変わらないという結果でした!
次回はINDEXとか追加して検証してみます。。。
コメント