C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[9]: 抽出データの多い時


(過去ログ 38 を表示中)

[トピック内 25 記事 (1 - 20 表示)]  << 0 | 1 >>

■19529 / inTopicNo.1)  抽出データの多い時
  
□投稿者/ みちる (2回)-(2008/05/24(Sat) 21:10:57)

分類:[ASP.NET (VB)] 

ORACLE10g VB.NETです
データベースよりデータを抽出しますが、検索結果により数百万などになってしまう場合があります。
20秒以上掛かる場合、もしくは件数が1000を超える場合などでエラーを表示し処理を中断させたいです。

どういった方法があるのでしょうか。宜しくお願い致します
引用返信 編集キー/
■19530 / inTopicNo.2)  Re[1]: 抽出データの多い時
□投稿者/ Mr.T (254回)-(2008/05/24(Sat) 21:13:02)
Mr.Tです、こんにちは。
件数を最初に数えて、判断。
もし件数内であれば「1ページの表示に必要な分だけ」
そこから抽出したらよいのではないでしょうか。

No19529 (みちる さん) に返信
> ORACLE10g VB.NETです
> データベースよりデータを抽出しますが、検索結果により数百万などになってしまう場合があります。
> 20秒以上掛かる場合、もしくは件数が1000を超える場合などでエラーを表示し処理を中断させたいです。
>
> どういった方法があるのでしょうか。宜しくお願い致します
引用返信 編集キー/
■19531 / inTopicNo.3)  Re[1]: 抽出データの多い時
□投稿者/ はつね (740回)-(2008/05/24(Sat) 21:18:13)
No19529 (みちる さん) に返信
> どういった方法があるのでしょうか。宜しくお願い致します

実際に取得する前にSELECT COUNT(*)で件数を数えて判断。

引用返信 編集キー/
■19532 / inTopicNo.4)  Re[2]: 抽出データの多い時
□投稿者/ はつね (741回)-(2008/05/24(Sat) 21:20:16)
No19530 (Mr.T さん) に返信
> もし件数内であれば「1ページの表示に必要な分だけ」
> そこから抽出したらよいのではないでしょうか。

ページ制御するならば、数百万件あったとしてもエラーにせずに
1頁分表示して、全頁数かレコード件数を表示してあげれば
いいじゃないかな。
Googleの検索結果みたいに。

引用返信 編集キー/
■19533 / inTopicNo.5)  Re[2]: 抽出データの多い時
□投稿者/ みちる (4回)-(2008/05/24(Sat) 22:25:56)
No19531 (はつね さん) に返信
> ■No19529 (みちる さん) に返信
>>どういった方法があるのでしょうか。宜しくお願い致します
>
> 実際に取得する前にSELECT COUNT(*)で件数を数えて判断。

ごめんなさい、そのカウントを取る処理は件数が多くてもパフォーマンス的問題は
ないのでしょうか
あとご確認ですが検索結果からトップの100件のみ取り出す場合と検索結果全てを取り出す場合、やはり速度的
違いが断然あるものでしょうか?100件取り出す場合WHERE句で結果から減らす形になるのでしょうか

宜しくお願い致します
引用返信 編集キー/
■19534 / inTopicNo.6)  Re[3]: 抽出データの多い時
□投稿者/ みちる (5回)-(2008/05/24(Sat) 22:26:46)
No19533 (みちる さん) に返信
> ■No19531 (はつね さん) に返信
>>■No19529 (みちる さん) に返信
> >>どういった方法があるのでしょうか。宜しくお願い致します
>>
>>実際に取得する前にSELECT COUNT(*)で件数を数えて判断。
>
> ごめんなさい、そのカウントを取る処理は件数が多くてもパフォーマンス的問題は
> ないのでしょうか
> あとご確認ですが検索結果からトップの100件のみ取り出す場合と検索結果全てを取り出す場合、やはり速度的
> 違いが断然あるものでしょうか?100件取り出す場合WHERE句で結果から減らす形になるのでしょうか
>
> 宜しくお願い致します

あとですが自分が調べた中でプログラム上からfetchsizeというものの指定がありますが、これを使って多い場合出さないなど
できないものでしょうか
引用返信 編集キー/
■19535 / inTopicNo.7)  Re[4]: 抽出データの多い時
□投稿者/ はつね (742回)-(2008/05/24(Sat) 22:40:53)
はつね さんの Web サイト
No19534 (みちる さん) に返信
> あとですが自分が調べた中でプログラム上からfetchsizeというものの指定がありますが、

fetchsizeって何に使うか(使うとどうなるか)調べてみましたか?


引用返信 編集キー/
■19536 / inTopicNo.8)  Re[3]: 抽出データの多い時
□投稿者/ やじゅ (404回)-(2008/05/24(Sat) 22:48:58)
やじゅ さんの Web サイト
2008/05/24(Sat) 23:36:18 編集(投稿者)
2008/05/24(Sat) 23:00:24 編集(投稿者)

No19533 (みちる さん) に返信
>
>実際に取得する前にSELECT COUNT(*)で件数を数えて判断。
>
> ごめんなさい、そのカウントを取る処理は件数が多くてもパフォーマンス的問題は
> ないのでしょうか

件数が多ければ、それなりのパフォーマンスの違いは出てきます。

> あとご確認ですが検索結果からトップの100件のみ取り出す場合と検索結果全てを取り出す場合、やはり速度的
> 違いが断然あるものでしょうか?100件取り出す場合WHERE句で結果から減らす形になるのでしょうか
>

サーバー側ではどちらもI/Oの負荷は変わらないかもしれませんね。
ソートがある場合、全件走査しないと結果が分からないことですし。

クライアント側ではトップの100件のみとした場合、結果の総データ量が少ないので、
クライアントとの通信負荷(ネットワーク経由の場合はネットワーク)は少なくなりますので、
断然違いはあります。
※追記:一度に全件取得する場合にはですね。
引用返信 編集キー/
■19537 / inTopicNo.9)  Re[3]: 抽出データの多い時
□投稿者/ はつね (743回)-(2008/05/24(Sat) 23:04:52)
No19533 (みちる さん) に返信
>>実際に取得する前にSELECT COUNT(*)で件数を数えて判断。
>
> ごめんなさい、そのカウントを取る処理は件数が多くてもパフォーマンス的問題は
> ないのでしょうか

何に比べてでしょうか?
取得していって、1000件超えたらエラーとかするのであれば、
COUNT(*)で数えてしまった方が断然早いです。


> あとご確認ですが検索結果からトップの100件のみ取り出す場合と
> 検索結果全てを取り出す場合、やはり速度的違いが断然あるもの

検索に10秒、100件取り出すごとに1秒かかると仮定してみましょう。
100件だけとりだすならば、10+1で11秒。
10000件とりだしたら、10+1*100で110秒。

それだけじゃなくて、何百万件もあるデータをすべて取り出して、
すべてWEBアプリで表示しようとしたらブラウザに画面が表示され
るまでどれくらいまてばいいか想像つきません。

処理速度の違いを体感したいのならば、計測してみるのが1番ですよ。
特に何百万件もあるデータが手元にあるのならば、計測も楽ちんかと。

引用返信 編集キー/
■19539 / inTopicNo.10)  Re[4]: 抽出データの多い時
□投稿者/ やじゅ (405回)-(2008/05/25(Sun) 09:21:34)
やじゅ さんの Web サイト
> ■No19533 (みちる さん) に返信

参考リンク
Oracle SQLチューニング講座
http://www.atmarkit.co.jp/fdb/index/index-db.html#tuneorasql

ROW_NUMBER()で実行速度が遅い
http://otn.oracle.co.jp/forum/thread.jspa?threadID=2001064&start=30&tstart=0

Oracleのオプティマイザ
http://www.int21.co.jp/pcdn/oracle/article/optimizer.html
引用返信 編集キー/
■19576 / inTopicNo.11)  Re[4]: 抽出データの多い時
□投稿者/ Algol (14回)-(2008/05/26(Mon) 11:51:46)
2008/05/26(Mon) 11:58:12 編集(投稿者)

No19537 (はつね さん) に返信
> ■No19533 (みちる さん) に返信
> >>実際に取得する前にSELECT COUNT(*)で件数を数えて判断。
>>
>>ごめんなさい、そのカウントを取る処理は件数が多くてもパフォーマンス的問題は
>>ないのでしょうか
>
> 何に比べてでしょうか?
> 取得していって、1000件超えたらエラーとかするのであれば、
> COUNT(*)で数えてしまった方が断然早いです。
>
>
>>あとご確認ですが検索結果からトップの100件のみ取り出す場合と
>>検索結果全てを取り出す場合、やはり速度的違いが断然あるもの
>
> 検索に10秒、100件取り出すごとに1秒かかると仮定してみましょう。
> 100件だけとりだすならば、10+1で11秒。
> 10000件とりだしたら、10+1*100で110秒。
>
> それだけじゃなくて、何百万件もあるデータをすべて取り出して、
> すべてWEBアプリで表示しようとしたらブラウザに画面が表示され
> るまでどれくらいまてばいいか想像つきません。
>
> 処理速度の違いを体感したいのならば、計測してみるのが1番ですよ。
> 特に何百万件もあるデータが手元にあるのならば、計測も楽ちんかと。
>

テーブルの件数を調べるだけなら、where に rownum <= 1001 とすると多少早くなるかと思います。

select count(*) from test where rownum <= 1001

こうすると1001件までしかサンプリングしません

# 5万件のテーブルの件数取得で 0.1秒くらいの差ってとこでした…(汗
# 5万件取得 0.156秒 / 1001件取得 0.047秒
引用返信 編集キー/
■19581 / inTopicNo.12)  Re[5]: 抽出データの多い時
□投稿者/ じゅで (8回)-(2008/05/26(Mon) 12:46:17)
count(*)を使うよりcount(カラム名)の方が速かった気がします。
SQL Serverで昔言われたので、実際に速度をはかってみてはいないですが。
伝票No.とかで、必ず一意になるなら、カラム名を指定してみては?
程度です。
自分で調べてないので、自信なしですがorz
引用返信 編集キー/
■19589 / inTopicNo.13)  Re[6]: 抽出データの多い時
□投稿者/ PATIO (70回)-(2008/05/26(Mon) 15:28:09)
多分、試してみる事が出来る環境はお持ちのはずだと思いますので
ここで聞くよりもまず試してみるべきかと思います。
掲示板で聞くのは試してみてからでも遅くないはずです。

データベースの登録状態やらチューニングをどの程度やっているか等
あなた自身の環境で無いと分からない内容がたくさんあるはずです。
試すだけならマネージャー系のソフトを立ち上げてそのデータベースに接続して
直接、SQL文を実行するだけでもいいはずですし。
(わざわざプログラミングまでする必要は無いのではと言う意味です)

皆さん、言われていますが、データを返却する手間が無い分だけcount(*)を使った方が
早いのは間違い無いと思います。但し、それがどの程度早いのかは自分で確認するべき
かと思います。

引用返信 編集キー/
■19632 / inTopicNo.14)  Re[6]: 抽出データの多い時
□投稿者/ はつね (747回)-(2008/05/27(Tue) 00:34:18)
2008/05/27(Tue) 01:01:49 編集(投稿者)

No19581 (じゅで さん) に返信
> count(*)を使うよりcount(カラム名)の方が速かった気がします。

Oracleではcount(*)でやることにより、最適なINDEXを使用します。
PKよりも最適なINDEXを使うようになりますが変にカラムを指定してしまうと、その最適化が行われません。

SQL Serverはそこまでの最適化を行うかどうかは分かりませんが、SQL Server 2005 Express Editionで確認したところ、
COUNT(*)=COUNT(PK項目)<COUNT(非PK項目)
という事で変に項目指定するよりもCOUNT(*)の方が早かったです。

引用返信 編集キー/
■19633 / inTopicNo.15)  Re[5]: 抽出データの多い時
□投稿者/ はつね (748回)-(2008/05/27(Tue) 01:40:26)
No19576 (Algol さん) に返信
> テーブルの件数を調べるだけなら、where に rownum <= 1001 とすると多少早くなるかと思います。

実行プラン的には、COUNT STOPKEYというのが追加になりますね。


> select count(*) from test where rownum <= 1001
>
> こうすると1001件までしかサンプリングしません
>
> # 5万件のテーブルの件数取得で 0.1秒くらいの差ってとこでした…(汗
> # 5万件取得 0.156秒 / 1001件取得 0.047秒

データのキャッシュなどの影響を除くためDBリブートして計測したのですが、
明確な時間差が生じませんでした。
明日、時間があれば500万件くらいのデータで計っています。

引用返信 編集キー/
■19640 / inTopicNo.16)  Re[6]: 抽出データの多い時
□投稿者/ Algol (18回)-(2008/05/27(Tue) 09:28:49)
2008/05/27(Tue) 11:01:32 編集(投稿者)

No19633 (はつね さん) に返信
> データのキャッシュなどの影響を除くためDBリブートして計測したのですが、
> 明確な時間差が生じませんでした。
> 明日、時間があれば500万件くらいのデータで計っています。

おぉ、検証ありがとうございます。
500万件だと差が出るかもですねぇ。
便乗になってしまいますが、よろしくお願いします。

# 今500万件で検証できる環境が無いのでどんな結果が出るかちょっと楽しみです。
# 環境が無ければ作れば良いというダケの話ではあるのですが…大汗
# いま運用鯖しかないもので…汗

# 失礼だった語句訂正
# ありがとうです → ありがとうございます。

引用返信 編集キー/
■19643 / inTopicNo.17)  Re[7]: 抽出データの多い時
□投稿者/ こあら (2回)-(2008/05/27(Tue) 09:55:55)
> # 今500万件で検証できる環境が無いので
select count(*) from test as t1, test as t2
testテーブルに1000件入っているとして、このSQLで百万件のテストができます。


> # いま運用鯖しかないもので
ハードウェアスペック的に、ということでしたら失礼致しました。


> COUNT(*)=COUNT(PK項目)<COUNT(非PK項目)
> という事で変に項目指定するよりもCOUNT(*)の方が早かったです。
DBMSによっては COUNT(1) が速いという都市伝説を聞いたことがあります。
# exists (select 1 from ...) みたいなものでしょうか?

引用返信 編集キー/
■19646 / inTopicNo.18)  Re[8]: 抽出データの多い時
□投稿者/ Algol (19回)-(2008/05/27(Tue) 10:37:26)
2008/05/27(Tue) 11:07:18 編集(投稿者)
2008/05/27(Tue) 10:52:16 編集(投稿者)
2008/05/27(Tue) 10:46:02 編集(投稿者)

No19643 (こあら さん) に返信
>># 今500万件で検証できる環境が無いので
> select count(*) from test as t1, test as t2
> testテーブルに1000件入っているとして、このSQLで百万件のテストができます。
>
>># いま運用鯖しかないもので
> ハードウェアスペック的に、ということでしたら失礼致しました。
>
(以下ばっさり)

SQLで水増しされた件数とリアルデータの件数での差異はどうでしょう?
キャッシュなどの影響は絡んでこないでしょうか?

# うちの環境の話になってしまいますが…汗
# 開発はVMなので実質的な速度検証はあまり意味が無いですし…
# テスト的な環境を作るにしてもハードが無いので…汗
# *追記*
# ちなみに、上記で示した5万件の速度結果は運用で使われているリアル5万件のデータです。
# ただ、リブートできないのでキャッシュが絡んでる可能性大ですが…大汗
# *追記2*
# 本来であれば別スレを立てるべき内容であると思われるので続きそうであれば別スレにしようと思いますがどうでしょう?
引用返信 編集キー/
■19647 / inTopicNo.19)  Re[9]: 抽出データの多い時
□投稿者/ はつね (749回)-(2008/05/27(Tue) 11:14:32)
はつね さんの Web サイト
2008/05/27(Tue) 11:14:43 編集(投稿者)

No19646 (Algol さん) に返信
> SQLで水増しされた件数とリアルデータの件数での差異はどうでしょう?
> キャッシュなどの影響は絡んでこないでしょうか?

上記ですが、キャッシュされちゃうので物理リード部分は異なると思います。

引用返信 編集キー/
■19648 / inTopicNo.20)  Re[9]: 抽出データの多い時
 
□投稿者/ こあら (3回)-(2008/05/27(Tue) 11:26:57)
No19646 (Algol さん) に返信
> SQLで水増しされた件数とリアルデータの件数での差異はどうでしょう?

差異はあります。
ですが、パフォーマンス測定は「ある特定の条件下」で相対的に比較しますので、
その差異に注目する必要は無いと思います。

つまり、
test=1,000件で以下の測定値を比較しても、
> select count(*) from test as t1, test as t2
> select count(*) from test as t1, test as t2 where rownum <= 1001

test=1,000,000件で以下の測定値を比較しても、
> select count(*) from test
> select count(*) from test where rownum <= 1001

rownumの有無でどのくらいパフォーマンスが変化するのか?という点では、
比較が可能だと言う意見です。

もちろん「select count(*) from test as t1, test t2」が、
「select count(*) from testの2乗を返す」のような、特殊な最適化が行われないという前提ですが。
そして、そのような前提を排除する目的で、testテーブルに500万件用意する、
というのは一つの方法だと思います。


それから蛇足かもしれませんが COUNT(nullを許容する項目) は、
COUNT(*)と異なる値を返す場合があります。
#カウント項目がnullのレコードはカウントされません。

引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -