2010-12-14 13 views
0

WITH NOCHECKを使用してFKを追加すると、クエリオプティマイザは生成するクエリプランでこのFKを使用しません。それで、クエリ・オプティマイザは、どのように、なぜ、なぜクエリ・プランを生成するときにFKを考慮することになるか考えていましたか? FKが存在する場合、クエリエンジンにどのようなメリットがありますか?クエリオプティマイザとFK制約

答えて

2

外部キーが "信頼できる"場合、SQL Serverは、制約の対象となる列が他のテーブルの一意のインデックスにあるという事実を使用できます。 FKが対象とするテーブルとの結合があり、キーにある列のみを使用すると、結合が削除されます。 OrderProduct、およびOrderテーブルがProduct.Idへの外部キーであるProductIdがあります

たとえば、あなたが2つのテーブルを持っているとしましょう。次に、オプティマイザは知っていることは、このクエリ:

SELECT Order.Id, Order.ProductId 
FROM Order 

...と余分はProductに参加削除することができます。

SELECT Order.Id, Product.Id 
FROM Order 
LEFT OUTER JOIN Product ON Product.Id = Order.ProductId 

が...このクエリと同じです。これは、Orderに各行のProductの行が1つしかなく、値が同じであることがわかっているため、結合を削除してもクエリには影響しません。

Order.ProductIdがNULLでない場合、INNER JOINに対して同じことを実行できます。 null可能な場合は、Productに行があることがわからないため結合できないため、結合によってOrder行が削除される可能性があります。それは同じではありません。

ただし、Product.NameをSELECT句に追加すると、いずれの場合も結合を削除できません。

ええ、私は知っています:それは非常に便利ではないようです。実際には、これが実際に大きな違いを生むケースはあまりありません。通常、動的に生成されたSQLまたはコード生成では、結合が固定され、SELECT句のみが変更されます。

あなたがここにこのことについて読むことができます:それはコラムでは、おそらくいないすべての値ことを意味し、キーは「信頼」ではありません指定された場合WITH NOCHECKは、違いを理由については

http://explainextended.com/2009/10/15/constraints-and-the-optimizer-in-sql-server-foreign-key/

を制約を満たす。 WITH NOCHECKは、に制約を適用するだけです。データです。古いデータは前提条件に違反する可能性があるため、SQL Serverはそのデータを安全に処理し、そこに結合を維持します。

0

他の外部キーテーブルを結合するクエリがあり、外部キー制約がある場合、クエリエンジンは外部テーブルインデックスを利用することができます。

SQL Server Management Studioでクエリの実行計画を確認することでテストできます。クエリ - >実績実行計画を含む。 FKとWITH NOCHECKで試してみてください。

+0

これは可能かもしれませんが、クエリで使用できるインデックスを特定するためにクエリエンジンにFKが必要であるとは思われません。また、FKが存在するという理由だけで、FK列に索引が存在するわけではありません。 –

+0

@Randy - 実際には、FKは_target_テーブルにインデックスが存在するだけでなく、インデックスが一意であることを意味します。これは、dsumが "foreign table index"と言っていることです。しかし、FKが指し示すテーブルにのみインデックスが存在しているわけではありません。 – Tadmas