Mengapa statistik yang dibuat secara otomatis pada kolom ini kosong?

8

Info

Pertanyaan saya berkaitan dengan tabel yang cukup besar (~ ruang data 40GB) yang merupakan tumpukan
(Sayangnya, saya tidak diizinkan untuk menambahkan indeks berkerumun ke tabel oleh pemilik aplikasi)

Statistik yang dibuat secara otomatis pada kolom Identity ( ID) telah dibuat, tetapi kosong.

  • Statistik pembuatan otomatis & statistik pembaruan otomatis aktif
  • Modifikasi telah terjadi pada tabel
  • Ada statistik (otomatis dibuat) lainnya yang diperbarui
  • Ada statistik lain pada kolom yang sama yang dibuat oleh indeks (duplikat)
  • Bangun: 12.0.5546

Statistik duplikat semakin diperbarui: masukkan deskripsi gambar di sini

Pertanyaan sebenarnya

Menurut pemahaman saya, semua statistik dapat digunakan dan modifikasi dilacak, bahkan jika ada dua statistik pada kolom yang persis sama (duplikat), jadi mengapa statistik ini tetap kosong?

Info Statistik

masukkan deskripsi gambar di sini

Info stat DB

masukkan deskripsi gambar di sini

Ukuran Meja

masukkan deskripsi gambar di sini

Informasi kolom tempat dibuatnya statistik

masukkan deskripsi gambar di sini

[ID] [int] IDENTITY(1,1) NOT NULL

Kolom identitas

select * from sys.stats  
where name like '%_WA_Sys_0000000A_6B7099F3%';

masukkan deskripsi gambar di sini Dibuat otomatis

Dapatkan info tentang statistik lain

select * From sys.dm_db_stats_properties (1802541555, 3)  

masukkan deskripsi gambar di sini

Dibandingkan dengan stat kosong saya:

masukkan deskripsi gambar di sini

Statistik + Histogram dari "menghasilkan skrip":

/****** Object:  Statistic [_WA_Sys_0000000A_6B7099F3]    Script Date: 2/1/2019 10:18:19 AM ******/

    CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000

Saat membuat salinan statistik, tidak ada data di dalamnya

CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3_TEST] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000

masukkan deskripsi gambar di sini

Ketika secara manual memperbarui stat mereka diperbarui.

UPDATE STATISTICS [dbo].[Table]([_WA_Sys_0000000A_6B7099F3_TEST])

masukkan deskripsi gambar di sini

Randi Vertongen
sumber

Jawaban:

9

Saya dapat mereproduksi ini, baik dengan statistik kosong, dan statistik penduduk. Saya mengatur agar statistik otomatis dibuat di tabel kosong, dan indeks dibuat kemudian:

IF OBJECT_ID(N'dbo.Heap', N'U') IS NOT NULL
BEGIN
    DROP TABLE dbo.Heap;
END;
GO
CREATE TABLE dbo.Heap 
(
    id integer NOT NULL IDENTITY,
    val integer NOT NULL,
);
GO
-- Add 1000 rows
INSERT dbo.Heap
    WITH (TABLOCKX)
    (val)
SELECT
    SV.number
FROM master.dbo.spt_values AS SV
WHERE
    SV.[type] = N'P'
    AND SV.number BETWEEN 1 AND 1000;
GO
SELECT COUNT_BIG(*) 
FROM dbo.Heap AS H
JOIN dbo.Heap AS H2
    ON H2.id = H.id
WHERE H.id > 0
AND H2.id > 0;
GO
-- Empty table
TRUNCATE TABLE dbo.Heap;
GO
-- Repeat exact same query (RT = 500 + 0.2 * 1000 = 700)
GO
SELECT COUNT_BIG(*) 
FROM dbo.Heap AS H
JOIN dbo.Heap AS H2
    ON H2.id = H.id
WHERE H.id > 0
AND H2.id > 0;
GO
-- Add 1000 rows
INSERT dbo.Heap
    WITH (TABLOCKX)
    (val)
SELECT
    SV.number
FROM master.dbo.spt_values AS SV
WHERE
    SV.[type] = N'P'
    AND SV.number BETWEEN 1 AND 1000;
GO
-- Add index
ALTER TABLE dbo.Heap ADD 
    CONSTRAINT [PK dbo.Heap id]
    PRIMARY KEY NONCLUSTERED (id);
GO
SELECT
    S.[name],
    S.auto_created,
    DDSP.stats_id,
    DDSP.last_updated,
    DDSP.[rows],
    DDSP.rows_sampled,
    DDSP.steps,
    DDSP.unfiltered_rows,
    DDSP.modification_counter
FROM sys.stats AS S
CROSS APPLY sys.dm_db_stats_properties(S.[object_id], S.stats_id) AS DDSP
WHERE 
    S.[object_id] = OBJECT_ID(N'dbo.Heap', N'U');

Keluaran

Saya menemukan bahwa modifikasi terus dilacak secara akurat pada semua duplikat yang tidak kosong, tetapi hanya satu statistik yang diperbarui secara otomatis (terlepas dari pengaturan asinkron).

Pembaruan statistik otomatis hanya terjadi ketika pengoptimal kueri memerlukan statistik tertentu, dan menemukan bahwa statistik tersebut kedaluwarsa (kompilasi terkait optimalitas).

Pengoptimal memilih dari statistik duplikat seperti yang disebutkan dalam paket Caching dan Kompilasi dalam makalah SQL Server 2012 :

Masalah yang tidak terkait langsung dengan topik dokumen ini adalah: diberikan beberapa statistik pada kumpulan kolom yang sama dalam urutan yang sama, bagaimana cara pengoptimal kueri memutuskan mana yang akan dimuat selama optimasi kueri? Jawabannya tidak sederhana, tetapi pengoptimal kueri menggunakan pedoman seperti: Berikan preferensi pada statistik terkini daripada statistik yang lebih lama; Berikan preferensi untuk statistik yang dihitung menggunakan FULLSCANopsi untuk mereka yang dihitung menggunakan sampling; dan seterusnya.

Intinya adalah bahwa pengoptimal memilih salah satu statistik duplikat yang tersedia (yang "terbaik), dan yang diperbarui secara otomatis jika ternyata basi.

Saya percaya ini adalah perubahan perilaku dari rilis yang lebih lama - atau setidaknya dokumentasi menunjukkan bahwa semua statistik out-of-date untuk suatu objek akan diperbarui sebagai bagian dari proses ini, tetapi saya tidak tahu kapan ini berubah. Itu pasti setelah Agustus 2013 ketika Matt Bowler memposting Statistik Duplikat , yang berisi repo berbasis AdventureWorks berguna. Skrip itu sekarang hanya menghasilkan satu dari objek statistik yang diperbarui, sementara pada saat itu keduanya.

Penjelasan di atas cocok dengan semua perilaku yang saya amati saat mencoba mereproduksi skenario Anda, tetapi saya ragu itu didokumentasikan secara eksplisit di mana saja. Itu memang tampak seperti optimasi yang masuk akal, karena ada sedikit nilai dalam menjaga duplikat diperbarui sepenuhnya.

Ini mungkin semua pada tingkat detail di bawah ini yang bersedia didukung oleh Microsoft. Ini juga berarti bisa berubah tanpa pemberitahuan.

Paul White 9
sumber