22

データベース内のテーブルを正規化し、それを非正規化するために、2つのテーブルからビューを作成しました。ビューにクラスター化インデックスを作成しようとすると、ビューが左外部結合で作成されたため、作成できませんでした。この以前の投稿で提案された方法と同じように、結果のビューにnull値を表示したいので、左結合を使用しました。

1つの列の片側がnullである結合に関する質問

テーブルの構造と関係は、上記のリンクで説明したものと非常によく似ています。

左結合を内部結合に変換できなかったため、ここで壁にぶつかったように見えました。これは、結合された列のいずれかでnull値を持つすべてのレコードを除外するためです。私の質問は次のとおりです。

  1. 外部結合または自己結合でインデックス作成が許可されないのはなぜですか?
  2. この種のインデックス付けされていないビューでパフォーマンスに影響はありますか?
  3. 誰かがこの問題の回避策を知っていますか?

昨日SQLServerコースを終了したばかりなので、続行する方法がわかりません。コメントをいただければ幸いです。乾杯。

4

5 に答える 5

14

これが代替案です。Bを含まないAのマテリアライズドビューが必要です。これは直接利用できません...代わりに、2つのビューをマテリアライズします。すべてのAの1つと、Bを持つAのみの1つ。次に、B以外のAを取得して、Bを持たないAのみを取得します。これは効率的に実行できます。

2つのマテリアライズドビュー(mAとmAB)を作成します(編集:mAは単なるベーステーブルである可能性があります)。mAには、AとBの間の結合がありません(したがって、すべてのAのピリオドが含まれています[したがって、Bに一致するものがないレコードが含まれています])。mABはAとBの間で結合します(したがって、AとBのみが含まれます[したがって、Bで一致しないレコードは除外されます])。

Bで一致しないすべてのAを取得するには、一致するものをマスクします。

with ids as (
  select matchId from mA with (index (pk_matchid), noexpand)
  except
  select matchId from mAB with (index (pk_matchid), noexpand)
)
select * from mA a join ids b on a.matchId = b.matchId;

これにより、IDを取得するためのクラスター化インデックスと、探しているmAからデータを取得しようとするクラスター化インデックスの両方に対して左アンチセミ結合が生成されます。

基本的に、あなたが遭遇しているのは、SQLはISNではないデータよりもそこにあるデータを処理するのにはるかに優れているという基本的なルールです。2つのソースを具体化することにより、いくつかの説得力のあるセットベースのオプションを得ることができます。これらのビューのコストとそれらの利益を自分で比較検討する必要があります。

于 2015-07-01T20:33:08.707 に答える
10

ここNULLには、結合をチェックNULL し、テーブルに表現値を含めることを含む「回避策」があります。

NULL値

INSERT INTO Father (Father_id, Father_name) values(-255,'No father')

参加する

JOIN [dbo].[son] s on isnull(s.father_id, -255) = f.father_id
于 2011-06-25T09:38:53.460 に答える
7

良い回避策はないと思います。これについてできることは、ビューから実際のテーブルを作成し、それにインデックスを設定することです。これは、データが更新されるときに定期的に呼び出されるストアドプロシージャによって実行できます。

Select * 
into <REAL_TABLE>
From <VIEW>

create CLUSTERED index <INDEX_THE_FIELD> on <REAL_TABLE>(<THE_FIELD>)

ただし、これは、データが数秒ごとに更新されない場合にのみ注目に値するアプローチです。

于 2012-11-26T14:20:35.440 に答える
1

論理的には、2つの別々のクエリを実行しています。「ALEFTJOINB」は、「(A JOIN B)UNIONA」の省略形です。

最初のクエリは、テーブルBに結合されたテーブルAの内部です。これは、すべての手間のかかる作業が行われる場所であるため、インデックス付きのビューを取得します。

2番目のクエリは、結合列のいずれかがnullであるテーブルAだけです。最初のクエリと同じ出力列を生成し、それらにnullを埋め込むビューを作成します。

それらを返す前に、2つの結果を結合するだけです。回避策は必要ありません。

于 2013-02-05T18:16:05.007 に答える
0

私は1の答えに取り組みますが、今のところ:

[2]。ビューのパフォーマンスは、上にあるテーブルの同等のクエリよりも高くも低くもなりません。カバーするインデックス、できれば結合された列のインデックスなどについては、通常のアドバイスがすべて適用されます。

[3]。実際の回避策はありません。インデックス付きビューに対する制限のほとんどは、それらを掘り下げてみると、非常に正当な理由で存在します。

通常、ビューを作成するだけで、特定のパフォーマンスの問題がない限り、それ以上は作成しません。

自分の頭の中で再構築したら、1の答えを追加しようと思います。

于 2011-06-25T09:34:08.280 に答える