- - PR -
SQLの性能
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2006-07-05 21:26
クエリ応答時間は45秒〜50秒です。。
自己結合するテーブルをビューにして実行してみました。 以下のような感じです。 SELECT A.column1,B.column2 from TableA A INNER JOIN ViewA B ON A.column3 = B.column1 これだと速くなったのですが、また別の疑問が。 上記クエリでいうところのTableAには条件をつけて検索を行っています。 SELECT A.column1,B.column2 from TableA A LEFTJOIN ViewA B ON A.column3 = B.column1 WHERE A.column1 in (1, 2, 3) ※関係ないかもしれませんが、INNER JOINではなく、外部結合でした。 ビューを作った後の最初の実行ではタイムアウトしましたが、2回目以降は速くなりました。 しかし、(1, 2, 3) の条件を(1, 2) のように変更すると、またタイムアウトし、2回目以降は速くなりました。 実行プランを見ましたが、これ以上特に問題はなさそうでしたし、インデックスウィザード(完全)でもインデックスの追加は出ませんでした。 また、今までのDBサーバとは別にSQL2000のサーバをたててDBを構築し、そちらでクエリを実行してみたところ、毎回5秒くらいで返ってきます。 実行プランも違う結果になりました。 今の私の技量では、手の施しようがないですね・・・。 | ||||
|
投稿日時: 2006-07-05 22:42
2回目以降が速いということは、実行プランの生成に時間がかかっているものと思われます。 インデックスの再構築と統計情報の更新を行って状況が変化するか見たほうがいいかとおもいます。 最適と思われる実行プランが抽出条件などによって変化しないのであれば ストアド化して実行プランをキャッシュしてみるなど、まだまだ手はあるはずです。 [ メッセージ編集済み 編集者: ハニワ祭り 編集日時 2006-07-05 22:44 ] | ||||
|
投稿日時: 2006-07-05 23:04
いろいろわからないことだらけで申し訳ないです。 チューニングに関しては素人なもので・・。 実行プランをキャッシュする方法を教えてください。 キャッシュすると、何が分かりますか? 結果的にストアドにした方が良いということになったりしますか? | ||||
|
投稿日時: 2006-07-06 00:17
ストアドにすれば通常実行プランはキャッシュされます。
ただし、Where句の条件によって、最適な実行プランが変化してしまう (=使用すべきインデックスが変化する)場合は、リコンパイルオプションをつける必要が でてくるため、ストアド化するメリットはあまりありません。 また、SQLSERVERはコストベースオブティマイザのみため、 インデックスが断片化していたり、統計情報が古かったりすると まともな実行プランが生成されないことがあります。 チューニングの基本は、 ・抽出するデータを最小限に絞り込むこと。 ・最適な実行プランを想定し、その実行プランが確実に生成されるように、 インデックスを作ったり一時テーブルやテーブル変数を使用しSQLSERVERに それ以外に選択の余地を与えないこと。 だと思います。 [ メッセージ編集済み 編集者: ハニワ祭り 編集日時 2006-07-06 00:18 ] | ||||
|
投稿日時: 2006-07-06 11:59
確かに相当複雑なプランになりそうですが、体感できるほどプラン生成に時間がかかる ものでしょうか。通常2度目のクエリ実行で速度が速くなるのは、インデックスやデータ ページがキャッシュに乗るからだと思うのですが。 実行プランには問題がない、とのことですが、絞込みの順番は想定どおりになっている でしょうか。条件から見て少ないデータを持つテーブルから絞込みが行われていないと インデックスを使っていてもパフォーマンスが出ない場合があります。 | ||||
|
投稿日時: 2006-07-06 22:33
クエリはごく単純なものです。 select SELECT列 from TableA A <TableAからの外部結合がいくつか> where A.column1 in (条件とする値が7000個) order by A.column1 column1は主キーです。 インデックスは関係あるんでしょうか? ()内の値の数を減らせば速くなってきます。 クエリの改善の余地はありますか? | ||||
|
投稿日時: 2006-07-06 23:00
検査するレコードが7000レコードではなく、 inの候補値が7000個だったら、遅くなるのはやむを得ないと思います。 例えば数字の場合 between などに変換できませんか? | ||||
|
投稿日時: 2006-07-06 23:59
数字ですが、範囲指定はできない仕様なんですよね。 | ||||
