オノデラの研究日記 in わんくま

思いついたネタを気ままに書いていくブログ

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  209  : 記事  5  : コメント  534  : トラックバック  37

ニュース

プロフィール

  • ●おのでら
    宮城県在住
    主に業務向けソフトを製作

Twitter

ニュース

主なリンク

XNA 関連リンク

アイテム

ゲーマーカード

その他

記事カテゴリ

書庫

日記カテゴリ

 こちらのページでたまたま見つけたんですが、count 関数に渡した列名によって返す値が変わったりしたんですね。

 例えば、

  1. SELECT COUNT(DEPT_NO) FROM USER_MASTER
  2. SELECT COUNT(*) FROM USER_MASTER

 とした場合、(1)では指定した列(DEPT_NO)に「NULL」が含まれている行はカウントされずに数を返します。(2)の場合は基本的に select した全ての行の数を返します(すべての列の値が NULL だったときはわかりません(^^;))。

 いくら(1)の方が早いからといって適当な列を指定してしまうと、後で痛い目を見るってことですね。(NULL 許容不可の列を指定すべきってことです)

投稿日時 : 2007年7月9日 12:48

コメント

# re: Oracle : count 関数の注意 2007/07/09 13:12 けろ
純粋に総件数だけカウントしたい場合は、要注意ですね。
次の案件、Oracleなんで、気をつけよっとw

# re: Oracle : count 関数の注意 2007/07/09 13:19 はつね
PK指定すればOKですね。


# re: Oracle : count 関数の注意 2007/07/09 13:19 はつね
#編集途中だったorz

PKに含まれている列を指定すればOKですね。


# re: Oracle : count 関数の注意 2007/07/09 13:37 片桐
はつねさんに一票。
というか、count(*)よりもcount(PK列)の方が早いとかいう話もありませんでしたっけ?

# re: Oracle : count 関数の注意 2007/07/09 14:22 HiJun
PKがついていないテーブルとかを考慮すると、ROWIDとかで
検索するべきなのかな...
(スピードの点からすると微妙かもしれませんが...)

# re: Oracle : count 関数の注意 2007/07/09 15:52 kox
条件の部分ではないので、ROWIDでいいと思いますよ。
(未確認)

# re: Oracle : count 関数の注意 2007/07/09 16:54 通り*
あれ?オラクルだけじゃなくてSQL Serverも同じゃないの?って思って今試したんですが、SQL ServerもAccessも同じでしたよ??
それと列全部がnullでもcount(*)は大丈夫でした。
たぶんパフォーマンスは全然変わらないような気がするので、count(ROWID)とかよりcount(*)の方が私はいいな...(そんな気分ですw)


# re: Oracle : count 関数の注意 2007/07/09 17:11 HiJun
いままで、列指定でCOUNTしていたけど、*でやったほうがいいのですね。
(NVLつけるのもだるいし...)

# re: Oracle : count 関数の注意 2007/07/09 17:48 ダッチ
Oracle 8.1.7 を使用していた頃は、count(ROWID) と count(*) でかなり差が出た記憶があります。count(*) は1秒や2秒ではなくそれ以上の時間がかかっていました。
最新のバージョンだと早いのかな?

# re: Oracle : count 関数の注意 2007/07/09 17:49 通り*
ググってみました!
SQL ServerのBooks Onlineに「この動作は SQL-92 標準で定義されています」って書かれてました。
http://technet.microsoft.com/ja-jp/library/ms138031.aspx
オラクルも準拠してるので、動作が同じなんでしょうね。
たぶんcount(*)用に最適化された処理があるんじゃないかな...(想像ですけど)


# re: Oracle : count 関数の注意 2007/07/09 17:55 片桐
ああ、そっか。
count関数って列指定の場合には、
count(distinct XXX) とか count(all XXX)とか書けるから、
列にNULLがあるかないかを意識しないとダメなのですね。
count(*) っていうのは、取ってきた全ての行数を表す関数だから、
同じcount()と書くのでも意味が違うってことだと思ってきたですよ。

つまり、この条件でこれの件数を数えたいねん!って時は列指定で、
とりあえず条件で取ってきた全部の件数!って時はcount(*)

あなたはどっち?ってことで(笑)

# re: Oracle : count 関数の注意 2007/07/09 18:03 通り*
#連続コメントごめんなさい。
#と思ったら片桐さんに間に入られた~w
#さっきはダッチさんと重なってしまいました。
またググってみました。すでに大昔にも議論されてました。
http://otn.oracle.co.jp/forum/message.jspa?messageID=3022155
結局どっち?(笑)


# re: Oracle : count 関数の注意 2007/07/10 0:06 オノデラ
たくさんのコメントありがとうございます。m(_ _)m

・けろ さん

単純に count 関数といっても渡せる値の形式がいろいろあるので結構注意しないといけないですね。

・はつね さん

なるほど、プライマリキーなら確実に値が入っているので安全ではありますね

・HiJun さん
・kox さん

ROWID を使う方法があるとは気づきませんでした(^^;)

・ダッチ さん

私の場合、10g しか使ったことがないんですけど、古いバージョンだと結構差が出ていたんですね。10g だと自動的に最適化してくれるのかな?

・片桐 さん

おおっ、count(distinct XXX) とか count(all XXX) なんて使い方もあったんですか!私もまだまだ勉強が足りませんな。

・通り* さん

なんかわざわざ調べてくださってありがとうございます。m(_ _)m
リンク先の説明に count 関数の仕様が書いてありましたね。勉強になりました。
私も個人的には count(*) の方が好きなんですが、SQL チューニングの一つとして count(XXX) があるので最近こっちを使うようにしていますが、 10g だとそこまでする必要も無いようなことも書いてありましたね。

# re: Oracle : count 関数の注意 2008/10/08 18:12 anony
count(1)とかいかがですか。

はやい、うまい、分かりにくい。


Post Feedback

タイトル
名前
Url:
コメント