web-dev-qa-db-ja.com

一時テーブルにインデックスを追加することは可能ですか?そして、create #tとdeclare @tの違いは何ですか

非常に複雑なクエリを実行する必要があります。ある時点で、このクエリには、残念ながらインデックスを作成できないビューへの結合が必要です。このビューは、大きなテーブルを結合する複雑なビューでもあります。

ビューの出力は次のように簡略化できます。

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レポート用です)。

14
Istrebitel

これは完全な答えではありませんが、#tableは、削除する必要がある一時テーブルを作成するか、データベースに永続化します。 @tableは、スクリプトより長く存続しないテーブル変数です。

また、この投稿はあなたの質問の他の部分に答えると思います。

テーブル変数にインデックスを作成する

2
Brian Dishaw

#tablenametempdbに格納されている物理テーブルであり、作成した接続が閉じられたときにサーバーが自動的にドロップします。@tablenameは、メモリに格納されており、ローカル変数のように、それを作成したバッチ/プロシージャ。

(非PK)インデックスのみを#tempテーブルに追加できます。

create table #blah (fld int)
create nonclustered index idx on #blah (fld)
7
Alex K.

はい、一時テーブルまたはテーブル変数にインデックスを作成できます。 http://sqlserverplanet.com/sql/create-index-on-table-variable/

2
JeffO

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
0
svonidze