genel geçici tabloda mantıksal okumalar, ancak oturum düzeyinde geçici tabloda değil


11

Aşağıdaki basit MCVE'yi düşünün:

SET STATISTICS IO, TIME OFF;
USE tempdb;

IF OBJECT_ID(N'tempdb..#t1', N'U') IS NOT NULL DROP TABLE #t1;
CREATE TABLE #t1
(
    r int NOT NULL
);

IF OBJECT_ID(N'tempdb..##t1', N'U') IS NOT NULL DROP TABLE ##t1;
CREATE TABLE ##t1
(
    r int NOT NULL
);

IF OBJECT_ID(N'dbo.s1', N'U') IS NOT NULL DROP TABLE dbo.s1;
CREATE TABLE dbo.s1 
(
    r int NOT NULL
        PRIMARY KEY CLUSTERED
);

INSERT INTO dbo.s1 (r)
SELECT TOP(10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM sys.syscolumns sc1
    CROSS JOIN sys.syscolumns sc2;
GO

Aşağıdaki ekleri çalıştırdığımda, eklediğinizde #t1geçici tablo için istatistik G / Ç görüntülenmiyor. Bununla birlikte, içine sokulması ##t1 yapar İstatistikleri göster I / sıcaklık tablo Ö.

SET STATISTICS IO, TIME ON;
GO

INSERT INTO #t1 (r)
SELECT r
FROM dbo.s1;

İstatistik çıktısı:

SQL Server ayrıştırma ve derleme zamanı: 
   CPU süresi = 0 ms, geçen süre = 1 ms.
Tablo 's1'. Tarama sayısı 1, mantıksal okumalar 19, fiziksel okumalar 0, okuma öncesi okumalar 0, lob mantıksal okumalar 0, lob fiziksel okumalar 0, lob okuma öncesi okumalar 0.

 SQL Server Yürütme Süreleri:
   CPU süresi = 16 ms, geçen süre = 9 ms.

(10000 satır etkilendi)
INSERT INTO ##t1 (r)
SELECT r
FROM dbo.s1;
SQL Server ayrıştırma ve derleme zamanı: 
   CPU süresi = 0 ms, geçen süre = 1 ms.
'## t1' tablosu. Tarama sayısı 0, mantıksal okuma 10016, fiziksel okuma 0, okuma öncesi okuma 0, lob mantıksal okuma 0, lob fiziksel okuma 0, lob okuma öncesinde okuma 0.
Tablo 's1'. Tarama sayısı 1, mantıksal okumalar 19, fiziksel okumalar 0, okuma öncesi okumalar 0, lob mantıksal okumalar 0, lob fiziksel okumalar 0, lob okuma öncesi okumalar 0.

 SQL Server Yürütme Süreleri:
   CPU süresi = 47 ms, geçen süre = 45 ms.

(10000 satır etkilendi)

## temp tablosunda yalnızca içine yerleştirdiğimde neden bu kadar çok okuma var?

Yanıtlar:


11

Genel INSERT INTOgeçici tablolar kullanılırken minimum günlük kaydı kullanılmıyor

Kullanarak bir küresel geçici tabloya bir milyon satır ekleme INSERT INTO

INSERT INTO ##t1 (r)
SELECT top(1000000) s1.r
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

Çalıştırırken SELECT * FROM fn_dblog(NULL, NULL)Yukarıdaki sorgu yürütülürken, ~ 1M satır döndürülür.

resim açıklamasını buraya girin

LOP_INSERT_ROWHer satır için bir işlem + diğer günlük verileri.


Yerel geçici tablodaki aynı kesici uç

INSERT INTO #t1 (r)
SELECT top(1000000) s1.r
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

Yalnızca 700 satıra kadar dönüyor SELECT * FROM fn_dblog(NULL, NULL)

resim açıklamasını buraya girin

Minimum kayıt tutma


Kullanarak bir küresel geçici tabloya bir milyon satır ekleme SELECT INTO

SELECT top(1000000) s1.r
INTO ##t2
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

resim açıklamasını buraya girin

SELECT INTO 10 bin kayıt içeren küresel bir sıcaklık tablosu

SELECT s1.r
INTO ##t2
FROM dbo.s1;

Zaman ve ES İstatistikleri

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 16 ms,  elapsed time = 10 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

Bu blog yazısına dayanarak, TABLOCKbir yığın tablosunda minimum günlük kaydını başlatmak için ekleyebiliriz

INSERT INTO ##t1 WITH(TABLOCK) (r)
SELECT   s1.r
FROM dbo.s1

Düşük mantıksal okumalar

Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(10000 rows affected)

@PaulWhite tarafından geçici tablolarda en az günlük kaydı nasıl elde edileceğine dair bir yanıtın parçası

Hayır. Yerel geçici tablolar (#temp) oluşturma oturumuna özeldir, bu nedenle tablo kilitleme ipucu gerekmez. Birden fazla oturumdan erişilebildiğinden geçici bir tablo (## temp) veya tempdb'de oluşturulan normal bir tablo (dbo.temp) için bir tablo kilidi ipucu gerekir.

Bunu test etmek için normal bir tablo oluşturma:

CREATE TABLE dbo.bla
(
    r int NOT NULL 
);

1 milyon kayıtla doldurma

INSERT INTO bla 
SELECT   top(1000000)s1.r
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

> Bu tabloda 1 milyon mantıksal okuma

Table 's1'. Scan count 17, logical reads 155, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'bla'. Scan count 0, logical reads 1001607, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Paul White'ın küresel sıcaklık tablosunda rapor edilen mantıksal okumaları açıklayan cevabı

Genel olarak, insert minimal olarak kaydedilmediğinde hedef tablo için mantıksal okumalar rapor edilir.

Bu mantıksal okumalar, yeni satırları eklemek için mevcut yapıda bir yer bulma ile ilişkilidir. En az günlüğe eklenen ekler, tüm yeni sayfaları / uzantıları ayıran toplu yükleme mekanizmasını kullanır (bu nedenle hedef yapıyı aynı şekilde okumasına gerek yoktur).


Sonuç

Sonuç, en INSERT INTOaz günlük kaydı kullanamayacağı, genel geçici tablo / normal tablo ile birlikte kullanıldığında eklenen her satırı tempdb günlük dosyasına tek tek kaydetmesine neden olacağı sonucudur . Yerel geçici tablo / SELECT INTO/ INSERT INTO ... WITH(TABLOCK)ise minimum günlük kaydı kullanabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.