前回から引き続き、3回目のSELECT COUNT(*)とSELECT COUNT(1)の処理速度検証を行います。
今回もレコード件数を100万件、500万件、1,000万件で各3回計測します。
前回の検証テーブルのカラム数は2カラムでしたが、今回は検証テーブルのカラム数を7カラムにして、ID以外の各項目にMAX桁を指定しています。カラム数を増やすと処理速度に違いがでるのでしょうか。
TB_MAINテーブルの定義
DESC TB_MAIN; 名前 NULL? 型 ------------ -------- ---------------------------- ID NOT NULL NUMBER(10) NAME VARCHAR2(12 CHAR) MEMO1 VARCHAR2(50 CHAR) MEMO2 VARCHAR2(50 CHAR) MEMO3 VARCHAR2(50 CHAR) MEMO4 VARCHAR2(50 CHAR) MEMO5 VARCHAR2(50 CHAR)
SELECT COUNT(*) / 100万件
SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 1000000経過: 00:00:01.30SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 1000000経過: 00:00:01.71SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 1000000経過: 00:00:01.35SELECT COUNT(*) FROM TB_MAIN; 実行計画 ---------------------------------------------------------- Plan hash value: 1942898894 ----------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ----------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 511 (0)| 00:00:07 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FAST FULL SCAN| SYS_C007667 | 1249K| 511 (0)| 00:00:07 | ----------------------------------------------------------------------------- Note ----- - dynamic sampling used for this statement (level=2) 統計 ----------------------------------------------------------0 recursive calls0 db block gets1891 consistent gets0 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 0 sorts (memory) 0 sorts (disk) 1 rows processed
SELECT COUNT(1) / 100万件
SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 1000000経過: 00:00:01.44SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 1000000経過: 00:00:01.19SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 1000000経過: 00:00:01.34SELECT COUNT(1) FROM TB_MAIN; 実行計画 ---------------------------------------------------------- Plan hash value: 1942898894 ----------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ----------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 511 (0)| 00:00:07 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FAST FULL SCAN| SYS_C007667 | 1249K| 511 (0)| 00:00:07 | ----------------------------------------------------------------------------- Note ----- - dynamic sampling used for this statement (level=2) 統計 ----------------------------------------------------------4 recursive calls0 db block gets1998 consistent gets0 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 0 sorts (memory) 0 sorts (disk) 1 rows processed
SELECT COUNT(*) / 500万件
SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 5000000経過: 00:00:02.70SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 5000000経過: 00:00:03.00SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 5000000経過: 00:00:02.60SELECT COUNT(*) FROM TB_MAIN; 実行計画 ---------------------------------------------------------- Plan hash value: 1942898894 ----------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ----------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 2738 (1)| 00:00:33 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FAST FULL SCAN| SYS_C007667 | 5308K| 2738 (1)| 00:00:33 | ----------------------------------------------------------------------------- Note ----- - dynamic sampling used for this statement (level=2) 統計 ----------------------------------------------------------0 recursive calls0 db block gets10118 consistent gets0 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 0 sorts (memory) 0 sorts (disk) 1 rows processed
SELECT COUNT(1) / 500万件
SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 5000000経過: 00:00:02.69SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 5000000経過: 00:00:02.93SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 5000000経過: 00:00:02.77SELECT COUNT(1) FROM TB_MAIN; 実行計画 ---------------------------------------------------------- Plan hash value: 1942898894 ----------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ----------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 2738 (1)| 00:00:33 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FAST FULL SCAN| SYS_C007667 | 5308K| 2738 (1)| 00:00:33 | ----------------------------------------------------------------------------- Note ----- - dynamic sampling used for this statement (level=2) 統計 ----------------------------------------------------------4 recursive calls0 db block gets10225 consistent gets0 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 0 sorts (memory) 0 sorts (disk) 1 rows processed
SELECT COUNT(*) / 1,000万件
SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 10000000経過: 00:00:03.14SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 10000000経過: 00:00:03.19SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 10000000経過: 00:00:03.34SELECT COUNT(*) FROM TB_MAIN; 実行計画 ---------------------------------------------------------- Plan hash value: 2295499258 ----------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ----------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 5503 (1)| 00:01:07 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FAST FULL SCAN| SYS_C007666 | 8743K| 5503 (1)| 00:01:07 | ----------------------------------------------------------------------------- Note ----- - dynamic sampling used for this statement (level=2) 統計 ----------------------------------------------------------0 recursive calls0 db block gets20074 consistent gets0 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 0 sorts (memory) 0 sorts (disk) 1 rows processed
SELECT COUNT(1) / 1,000万件
SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 10000000経過: 00:00:04.20SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 10000000経過: 00:00:03.79SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 10000000経過: 00:00:04.09SELECT COUNT(1) FROM TB_MAIN; 実行計画 ---------------------------------------------------------- Plan hash value: 2295499258 ----------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ----------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 5503 (1)| 00:01:07 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FAST FULL SCAN| SYS_C007666 | 8743K| 5503 (1)| 00:01:07 | ----------------------------------------------------------------------------- Note ----- - dynamic sampling used for this statement (level=2) 統計 ----------------------------------------------------------4 recursive calls0 db block gets20178 consistent gets0 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 0 sorts (memory) 0 sorts (disk) 1 rows processed
SELECT COUNT(*)、COUNT(1)の処理速度検証結果
100万件の測定結果
回数/平均 | SELECT COUNT(*) | SELECT COUNT(1) |
---|---|---|
1回目 | 1.30秒 | 1.44秒 |
2回目 | 1.71秒 | 1.19秒 |
3回目 | 1.35秒 | 1.34秒 |
平均 | 1.45秒 | 1.32秒 |
500万件の測定結果
回数/平均 | SELECT COUNT(*) | SELECT COUNT(1) |
---|---|---|
1回目 | 2.70秒 | 2.69秒 |
2回目 | 3.00秒 | 2.93秒 |
3回目 | 2.60秒 | 2.77秒 |
平均 | 2.77秒 | 2.80秒 |
1,000万件の測定結果
回数/平均 | SELECT COUNT(*) | SELECT COUNT(1) |
---|---|---|
1回目 | 3.14秒 | 4.20秒 |
2回目 | 3.19秒 | 3.79秒 |
3回目 | 3.34秒 | 4.09秒 |
平均 | 3.22秒 | 4.03秒 |
100万件、500万件では実行速度にほとんで違いはありませんが、1,000万件からは1秒近くSELECT COUNT(*)の方が速いですね。
実行計画は相変わらずどちらも変わらないですが、統計を確認すると『consistent gets(読み込まれたブロック数)』についてはSELECT COUNT(*)の方が少ないですね。
検証結果としてはSELECT COUNT(1)よりも、SELECT COUNT(*)の方が速いという結果になりました。
1,000万件あたりから処理速度の違いがでてきました。レコード件数やカラム数が少ないと処理速度の違いはないです。
億や兆のデータを扱っている場合はSELECT COUNT(*)を使った方が良さそうです。次回は検証結果をまとめたいと思います。
以上です。