OracleとEBSとSiebelと駄文と。

Oracle製品ファンとして、見たこと聞いたこと調べたことを綴っています。

表の件数を数える

基本操作ではありますけど、件数が数千万とか億なんて単位になってくると高速化をめざしたくなります。

基本技:SELECT COUNT(*) FROM 表名;

きほん。返ってくる結果は正確です。結果が返ってくるまで1時間以上を要した環境を見たことがありますが…。
ところで

SELECT COUNT(*) FROM 表名;

SELECT COUNT(1) FROM 表名;

って結局どう違うの?どっちが速いの?個人的に気になったのでgoogle先生に聞いてみました。Oracle7まではCOUNT(*)が速かったが今はどっちも同じだという説があるようです。実際10gで数億件のテーブルで試したところ、ほんとに違いは無かったです。

ヒント句をつけて:SELECT /*+ parallel(表名, n) */ COUNT(*) FROM 表名;

ヒント句なしバージョンは1スレッドですがこちらはnスレッドで処理します。コンピューターアーキテクチャ理解度が残念なレベルの私は「nは使うCPUの数」と考えることにしています。ヒント句の書き方はSQLリファレンス参照。
nを増やせば増やすほど速くなるかっていうとそうでもないようで、私が試した環境ではn=4あたりで時間は半分に、どんなに増やしても3割まで減らないという結果でした。SQLのネックはCPUではなく、ほぼdiskアクセスなんですね。

統計情報をとっているなら:SELECT num_rows FROM all_tables WHERE table_name = '表名';

これで返ってくる数字はアバウトです。でも、件数を調べる目的にもよりますが、数千万にもなってくるとだいたいの件数で充分なことも多いので。これなら数秒かからず結果が返ってきます。
アバウトといっても、統計情報取得時のサンプル数が適切であれば結構近い数字が出てきます。サンプル数は100%でないと結果が信用できないわけではなくて、数千万件の表なら10%でも。根拠は弱いですけど…いつか調べてみよう。