2009-05-14 10 views
3

私はカラムがuser_id、email、defaultのテーブルを持っています。デフォルトでは、メールがユーザーのデフォルトメールかどうかに応じて、「Y」または「N」が格納されます。各ユーザーは、デフォルトの電子メールを1つだけ持つことができます。2つのクエリの方が効率的ですか?

ユーザーがテーブルの更新または挿入を行っているとき、私のSPで、ユーザーがisDefaultを 'Y'として渡したかどうかを確認します。もしそうなら、私はデフォルト 'N'にするために、そのユーザーのすべてのエントリを更新する必要があります。私の質問はされています。デフォルトの

update table 
set default = 'N' 
where user_id = 'abc' 
and default = 'Y' 

(オーバーヘッド:無施錠の問題(複数のスレッドが特定のユーザのためのテーブルからデータを要求するわけではない)以上の時間が消費している次のクエリの中の1が存在しない考慮します= 'Y' チェックが)

OR

update table 
set default = 'N' 
where user_id = 'abc' 

(ユーザーのすべてのレコードを更新するオーバーヘッド)

答えて

1

ここに明確な答えはありません。あなたの効率は、ほとんどのレコードでdefault = 'N'の場合、最初のケースで最善のものになります。 2番目のケースでは、ほとんどの場合、デフォルト= 'Y'の場合に最適です。

ほとんどのユーザーにメールアドレスが1つしかない場合は、2番目のクエリを使用します。ほとんどのユーザーが少なくとも2人いる場合は、最初のユーザーを使用します。

+0

クエリの速度は最も重要な要素ではありません。不必要な更新が重いロックを引き起こすという事実と、更新が実際には変更されていない場合でもテーブルの上に定義されているUPDATEトリガを起動します。 –

0

クエリの速度はSEVに依存表の行数、索引、検査制約、外部キーおよび主キーなどのエラー要因。

少なくともSQL Serverでどちらが高速かを判断する最善の方法は、クエリを実行するときにインクルードクライアントの統計と実行計画を使用することです。それぞれの時間を比較し、最高のものを選んでください。

1

自分で試してみませんか? SQL Management Studioでは、両方のクエリを順番に実行し、「実際の実行計画を含める」を有効にします。どちらが高いかは、クエリが遅いことです。

5

99%の確信度で、私は最初のクエリがより効果的であると言うことができます。

クラスタリングキーはuser_idなので、UPDATE文は更新する行が非常に迅速に見つかるようにします。 SQL Serverでは、更新は論理的に削除されてから挿入されるため、非常に高価な操作になる可能性があります(単純な参照と比較して)。 UPDATEがレコードに排他ロックを必要とし、すべての兆候は、Oracleの前で声明1.

+0

ええ、OK。私の前のコメントの前にあなたの答えを読んだことがありますか?私はあなたの優れた理解に恥じます。 –

+0

@Aaron Alton:絶対に。行の排他ロックを取得するだけでなく、Oracleの場合、UNDO(pka ROLLBACK)にコピーされたブロックのコピーを事前に変更し、これらの変更はすべてREDOログに記録されます。原則として、更新する必要のない行は更新する必要はありません。 – spencer7593

1

を指しているという事実と、私はオプション1の並べ替えのために行くだろうと

カップル。

各ユーザーにデフォルトのエントリが1つしかないことを強制する一意のインデックスがあるとしたら、そのインデックスの関数を更新の一部として使用します。更新する必要がある行のみを更新します。さらに、一意のインデックスは、特定のユーザーのデフォルトの電子メールを取得するために必要な作業を最小限に抑えます。更新だけでなく、その関数を使用して行を取得する場所でも使用できます。

drop table user_email; 

create table user_email 
(userid varchar2(4) not null, default_ind varchar2(1) not null, 
email varchar2(30)); 

create unique index ue_x on user_email 
    (userid, decode(default_ind,'Y','Y',email)); 

insert into user_email (userid, default_ind, email) values ('fred','N','a'); 
insert into user_email (userid, default_ind, email) values ('fred','N','b'); 
insert into user_email (userid, default_ind, email) values ('fred','Y','c'); 

update user_email 
set default_ind = 'N' 
where userid = 'fred' 
and decode(default_ind,'Y','Y',email) = 'Y'; 

update user_email 
set default_ind = 'Y' 
where userid = 'fred' 
and email = 'a'; 

PS。 "オーバーヘッドのdefault = 'Y' check"は、それを更新するためにその列にアクセスする必要があるため、かなり重要ではありません。

関連する問題