- PR -

同じテーブルを複数回結合の書き方と性能

投稿者投稿内容
TWZZ
会議室デビュー日: 2008/10/24
投稿数: 7
投稿日時: 2008-10-27 18:28
インデックスの順番を変えて見たら、処理時間が激減!
いや恐ろしいです。

しかし、いまの書き方だとインデックスが使われないのはなぜかな?
検索条件の順番?

よろしければ教えていただきたいです。
よっしー
大ベテラン
会議室デビュー日: 2007/05/17
投稿数: 143
投稿日時: 2008-10-27 18:35
TWZZさん、こんにちは。

もしかして、順番適当だったのですか?それでは使われなくても不思議ではありません。
引用:

TWZZさんの書き込み (2008-10-27 18:28) より:
しかし、いまの書き方だとインデックスが使われないのはなぜかな?


インデックスの定義を提示しないと、誰もわかりませんよ。
無名tiger
常連さん
会議室デビュー日: 2008/04/18
投稿数: 36
投稿日時: 2008-10-27 20:54
引用:

TWZZさんの書き込み (2008-10-27 18:28) より:

しかし、いまの書き方だとインデックスが使われないのはなぜかな?
検索条件の順番?

よろしければ教えていただきたいです。



下記の資料を参照してください。
http://www.geocities.jp/mickindex/database/db_optimize.html#LocalLink9


_________________
カスタマイズ自由自在のスタートページ。
よっしー
大ベテラン
会議室デビュー日: 2007/05/17
投稿数: 143
投稿日時: 2008-10-28 10:07
引用:

無名tigerさんの書き込み (2008-10-25 22:57) より:
1)OR は IN で置き換えましょう。INなら索引が使用できます。
WHERE 日付 = @前日 OR 日付 = @前々日

WHERE 日付 IN ( @前日, @前々日)


INって、内部的にはORで検索すると思っていましたが、どうでしょう?
ためしに、クラスタ化インデックスと非クラスタ化インデックスで要素が4個のINを実行したところ、実行計画のシーク述語がOR条件と同じ動作でした。INもORもどちらもインデックスが利用できています。INの中が10,000個など多くなってくると恐らくどちらもインデックスを利用ないと思いますが。
無名tiger
常連さん
会議室デビュー日: 2008/04/18
投稿数: 36
投稿日時: 2008-10-28 12:00
引用:

よっしーさんの書き込み (2008-10-28 10:07) より:
引用:

無名tigerさんの書き込み (2008-10-25 22:57) より:
1)OR は IN で置き換えましょう。INなら索引が使用できます。
WHERE 日付 = @前日 OR 日付 = @前々日

WHERE 日付 IN ( @前日, @前々日)


INって、内部的にはORで検索すると思っていましたが、どうでしょう?
ためしに、クラスタ化インデックスと非クラスタ化インデックスで要素が4個のINを実行したところ、実行計画のシーク述語がOR条件と同じ動作でした。INもORもどちらもインデックスが利用できています。INの中が10,000個など多くなってくると恐らくどちらもインデックスを利用ないと思いますが。



こちらで索引を使用しているかどうかを確認しました。(Oracle 10g)
よっしーさんおっしゃったとおりINもORもどちらもインデックスが利用できています。

確認しないで軽率な発言失礼しました。


_________________
カスタマイズ自由自在のスタートページ。
http://firstpage.jp/

[ メッセージ編集済み 編集者: 無名tiger 編集日時 2008-10-28 12:03 ]
よっしー
大ベテラン
会議室デビュー日: 2007/05/17
投稿数: 143
投稿日時: 2008-10-28 12:28
引用:

無名tigerさんの書き込み (2008-10-28 12:00) より:
確認しないで軽率な発言失礼しました。


そんなことないですよ。私だって断定できるほど試してないですし、
私もINを使うことには同意見なので。
WHERE 日付 = @前日 OR 日付 = @前々日だと、販売数≧の条件がついた時に
WHERE 日付 = @前日 OR 日付 = @前々日 AND 販売数 >= 1000
という間違いも犯しやすいですしね。
TWZZ
会議室デビュー日: 2008/10/24
投稿数: 7
投稿日時: 2008-10-28 15:13
引用:

よっしーさんの書き込み (2008-10-27 18:35) より:
TWZZさん、こんにちは。

もしかして、順番適当だったのですか?それでは使われなくても不思議ではありません。
引用:

TWZZさんの書き込み (2008-10-27 18:28) より:
しかし、いまの書き方だとインデックスが使われないのはなぜかな?


インデックスの定義を提示しないと、誰もわかりませんよ。



返事が遅れてすみません。
確か主キーの順番は適当で決めたものですが、
その時はまだ今回の業務はなかったのでいままで問題なかったです。

インデックス定義は以下のようです:
CREATE TABLE 販売履歴(
商品コード nvarchar(13) NOT NULL,
日付 smalldatetime NOT NULL,
販売数 int NOT NULL,
CONSTRAINT PK_販売履歴 PRIMARY KEY CLUSTERED
(
商品コード ASC,
日付 ASC
))

SQLは以下:
-------------------------------------------------------------------------
SELECT
T1.商品コード,
T2.販売数 AS 前日販売数,
T3.販売数 AS 前々日販売数
FROM 商品 T1

LEFT JOIN 販売履歴 T2
ON T1.商品コード = T2.商品コード
AND T2.日付 = @前日

LEFT JOIN 販売履歴 T3
ON T1.商品コード = T3.商品コード
AND T3.日付 = @前々日
-------------------------------------------------------------------------

引用:

無名tigerさんの書き込み (2008-10-27 20:54) より:
下記の資料を参照してください。
http://www.geocities.jp/mickindex/database/db_optimize.html#LocalLink9



やはり検索条件の順番ですか?
でも上記のSQLだと、そうでもないみたいですが・・・
よっしー
大ベテラン
会議室デビュー日: 2007/05/17
投稿数: 143
投稿日時: 2008-10-28 16:59
引用:

TWZZさんの書き込み (2008-10-28 15:13) より:
やはり検索条件の順番ですか?
でも上記のSQLだと、そうでもないみたいですが・・・


データの分布によります。
既に業務が動いている状況で、主キーの見直しなんてなかなか出来ないでしょうし、
日付順に並んでいるほうが速いなら、非クラスタ化インデックスを追加すれば良いのでは?販売数を付加列として追加すればより良いと思います。
⇒商品履歴テーブルに更新があまりないという前提です。

スキルアップ/キャリアアップ(JOB@IT)