7

通常 1 ~ 10 行を含む一時テーブルを作成するストアド プロシージャがあります。このテーブルは、ストアド プロシージャの実行中に何度も切り捨てられ、埋められます。これは削除よりも高速であるため、切り捨てられます。この一時テーブルをテーブル変数に置き換えると、delete を使用するとペナルティが発生するため、パフォーマンスが向上しますか (切り捨てはテーブル変数では機能しません)。

テーブル変数は主にメモリ内にあり、一般に一時テーブルよりも高速ですが、切り捨てるのではなく削除する必要があるため、メリットが失われますか?

4

2 に答える 2

14

スクリプトに従って実行すると、テーブル変数の方が適切なオプションのようです

CREATE TABLE #Temp(
        ID INT
)

DECLARE @Int INT,
        @InnerInt INT
SELECT  @Int = 1,
        @InnerInt = 1

WHILE @Int < 50000
BEGIN
    WHILE @InnerInt < 10
    BEGIN
        INSERT INTO #Temp SELECT @InnerInt
        SET @InnerInt = @InnerInt + 1
    END
    SELECT @Int = @Int + 1,
            @InnerInt = 1
    TRUNCATE TABLE #Temp
END

DROP TABLE #TEMP

GO

DECLARE @Temp TABLE(
        ID INT
)

DECLARE @Int INT,
        @InnerInt INT
SELECT  @Int = 1,
        @InnerInt = 1

WHILE @Int < 50000
BEGIN
    WHILE @InnerInt < 10
    BEGIN
        INSERT INTO @Temp SELECT @InnerInt
        SET @InnerInt = @InnerInt + 1
    END
    SELECT @Int = @Int + 1,
            @InnerInt = 1
    DELETE FROM @Temp
END

SQL プロファイラーから

CPU     Reads   Writes  Duration
36375     2799937   0       39319

vs

CPU     Reads   Writes  Duration
14750   1700031 2       17376   
于 2010-04-15T15:41:44.220 に答える
9

率直に言って、エントリが 10 または 20 (または 100) しかない場合、速度の違いはサブナノ秒の領域になります。それを忘れてください - これであなたの脳の時間を 1 秒も無駄にしないでください - それは問題ではありません!

一般に

  • テーブル変数は、特定のサイズまでメモリ内に保持されます。それを超えると、tempdb一時テーブルと同様に、データベース内のディスクにもスワップ アウトされます。プラス: 一時テーブルにほんの一握りのエントリしかない場合、とにかく単一の 8k ページに格納されるのが最も好きで、エントリの 1 つにアクセスするとすぐに、そのページ全体 (したがって一時テーブル全体) がSQL Server のメモリ内に存在します。ここでも、テーブル変数にはあまりメリットがありません...

  • テーブル変数はインデックスも統計もサポートしていません。つまり、一握り以上のエントリがあり、特にこの「エンティティ」を検索してクエリする必要がある場合は、一時テーブルを使用したほうがよいでしょう。

全体として、私は個人的にテーブル変数よりも頻繁に一時テーブルを使用します。特に、10 を超えるエントリなどがある場合はそうです。一時テーブルにインデックスを付けて統計を取得できることは、通常、テーブル変数がパフォーマンスの面でもたらす可能性のある潜在的な利益と比較して、大きな利益をもたらします。

于 2010-04-15T16:31:01.133 に答える