一時テーブルとテーブル変数のINSERTパフォーマンスの違い


12

SQL Server 2005には次の問題があります。いくつかの行をテーブル変数に挿入しようとすると、一時テーブルを使用した同じ挿入に比べて時間がかかります。

これは、テーブル変数に挿入するコードです

DECLARE @Data TABLE(...)
INSERT INTO @DATA( ... )
SELECT ..
FROM ...

これは、一時テーブルに挿入するコードです

CREATE #Data TABLE(...)
INSERT INTO #DATA( ... )
SELECT ..
FROM ...
DROP TABLE #Data

一時テーブルにはキーもインデックスもありません。選択部分は2つのクエリで同じであり、選択によって返される結果の数は〜10000行です。選択を単独で実行するのに必要な時間は約10秒です。

一時テーブルバージョンの実行には最大10秒かかり、5分後にテーブル変数バージョンを停止する必要がありました。

クエリは一時テーブルへのアクセスを許可しないテーブル値関数の一部であるため、テーブル変数を使用する必要があります。

テーブル変数バージョンの実行計画 実行計画

一時テーブルバージョンの実行計画 実行計画

回答:


8

2つのプランの明らかな違いは、高速プランが並列で、低速プランが並列であるということです。

これは、テーブル変数に挿入するプランの制限の1つです。コメントで述べたように(そして、それはあたかもそれが望ましい効果を持っているかのように思われます)、あなたはやってみてください

INSERT INTO @DATA ( ... ) 
EXEC('SELECT .. FROM ...')

それが制限を回避するかどうかを確認します。


私はあなたが使用ことができなかったけれどもけれどもそれは、偉大な提案だったEXEC....機能に私が間違っていたと思います
Lamak

1
@Lamak-ドッ!これがOPで機能しないようにすることはできません。Invalid use of a side-effecting operator 'INSERT EXEC' within a function.周りの仕事かもしれない仕事けれども。OPENQUERY
マーティンスミス

、明確化のための感謝を知ってああ、良い
Lamak

2
一般的な経験則として、大量のデータセットが返されることが予想される場合は、テーブル変数を使用しないでください。この場合、一時テーブルは通常高速です。
HLGEM

1
@munissor、テーブル値関数を使用しないでください。より良いアドバイスが必要な場合は、正確にあなたがやっていることを投稿してください。
HLGEM

-1

テーブル変数には統計がないため、テーブル変数の速度が低下することがあり、オプティマイザは常に1つのレコードのみを想定します。

ただし、これがこの場合であることを保証することはできません。テーブル変数のクエリプランの「推定行」情報を確認する必要があります。


テーブル変数への挿入にどのような影響がありますか?
マーティンスミス

並列と直列の違いだけでなく、ハッシュとネストされたループ結合にも違いがあることがわかるように、それは起こっているように見えます、明らかに、オプティマイザーはテーブル変数が1つのレコードを心に保持しているので結果クエリのレコードも1つのレコードになります。これは、クエリの各部分の実際の統計を確認することを証明する唯一の方法ですが、実際には、テーブル変数を含むすべてのクエリはループ結合とシリアル処理になります。だからここでそれを疑うのは公平だと思う
ヨールハルブ13年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.