SQL

COUNT(*)とCOUNT(1)の性能検証・3回目

  • このエントリーをはてなブックマークに追加

前回から引き続き、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.30
SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 1000000
経過: 00:00:01.71
SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 1000000
経過: 00:00:01.35
SELECT 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 calls
0 db block gets
1891 consistent gets
0 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.44
SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 1000000
経過: 00:00:01.19
SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 1000000
経過: 00:00:01.34
SELECT 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 calls
0 db block gets
1998 consistent gets
0 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.70
SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 5000000
経過: 00:00:03.00
SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 5000000
経過: 00:00:02.60
SELECT 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 calls
0 db block gets
10118 consistent gets
0 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.69
SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 5000000
経過: 00:00:02.93
SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 5000000
経過: 00:00:02.77
SELECT 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 calls
0 db block gets
10225 consistent gets
0 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.14
SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 10000000
経過: 00:00:03.19
SELECT COUNT(*) FROM TB_MAIN; COUNT(*) ---------- 10000000
経過: 00:00:03.34
SELECT 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 calls
0 db block gets
20074 consistent gets
0 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.20
SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 10000000
経過: 00:00:03.79
SELECT COUNT(1) FROM TB_MAIN; COUNT(1) ---------- 10000000
経過: 00:00:04.09
SELECT 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 calls
0 db block gets
20178 consistent gets
0 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(*)を使った方が良さそうです。次回は検証結果をまとめたいと思います。

以上です。

  • このエントリーをはてなブックマークに追加

コメントを残す

*