非常に複雑なクエリを実行する必要があります。ある時点で、このクエリには、残念ながらインデックスを作成できないビューへの結合が必要です。このビューは、大きなテーブルを結合する複雑なビューでもあります。
ビューの出力は次のように簡略化できます。
PID (int), Kind (int), Date (date), D1,D2..DN
ここで、PIDおよび日付と種類フィールドは一意ではありません(pid、種類、日付の同じ組み合わせを持つ複数の行がある場合があります)が、次のように結合で使用されます。
left join ComplexView mkcs on mkcs.PID=q4.PersonID and mkcs.Date=q4.date and mkcs.Kind=1
left join ComplexView mkcl on mkcl.PID=q4.PersonID and mkcl.Date=q4.date and mkcl.Kind=2
left join ComplexView mkco on mkco.PID=q4.PersonID and mkco.Date=q4.date and mkco.Kind=3
さて、このようにすると、複雑なビューが想定した3回実行されるため、クエリの実行にかなりの時間がかかります。その膨大な行のうち、実際に使用されるのは一部のみです(たとえば、40000のうち、2000だけが中古)
私がしたことは、@ temptableを宣言し、@ temptable select * from ComplexView where Insert ...に挿入することです-クエリごとに1回、ComplexViewから使用する行のみを選択してから、この@temptableに参加しています。
これにより、実行時間が大幅に短縮されました。
ただし、データベースにテーブルを作成し、PID、Kind、Date(非一意のクラスター化)にクラスター化インデックスを追加し、このテーブルからデータを取得すると、このテーブルから*を削除してこれに挿入することに気付きました複雑なビューのテーブルは数秒(3または4)かかり、クエリでこのテーブルを使用する(3回左に結合する)と、クエリ時間が半分(1分から30秒)に短縮されます。
だから、私の質問は、まず第一に-宣言された@temptablesにインデックスを作成することは可能ですか?そして、私は人々が「create #temptable」構文について話すのを見てきました。多分これは私が必要なものですか? declare @temptableとcreate #temptableの違いは何ですか?私のようなクエリには何を使用しますか? (このクエリは、必要に応じてMS Reporting Servicesレポート用です)。
これは完全な答えではありませんが、#tableは、削除する必要がある一時テーブルを作成するか、データベースに永続化します。 @tableは、スクリプトより長く存続しないテーブル変数です。
また、この投稿はあなたの質問の他の部分に答えると思います。
#tablename
はtempdb
に格納されている物理テーブルであり、作成した接続が閉じられたときにサーバーが自動的にドロップします。@tablename
は、メモリに格納されており、ローカル変数のように、それを作成したバッチ/プロシージャ。
(非PK)インデックスのみを#temp
テーブルに追加できます。
create table #blah (fld int)
create nonclustered index idx on #blah (fld)
はい、一時テーブルまたはテーブル変数にインデックスを作成できます。 http://sqlserverplanet.com/sql/create-index-on-table-variable/
Alex K.の答えを拡張するには、あなたはcan一時テーブルにPRIMARY KEY
を作成します
IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
DROP TABLE #tempTable
CREATE TABLE #tempTable
(
Id INT PRIMARY KEY
,Value NVARCHAR(128)
)
INSERT INTO #tempTable
VALUES
(1, 'first value')
,(3, 'second value')
-- will cause Violation of PRIMARY KEY constraint 'PK__#tempTab__3214EC071AE8C88D'. Cannot insert duplicate key in object 'dbo.#tempTable'. The duplicate key value is (1).
--,(1, 'first value one more time')
SELECT * FROM #tempTable