Bagaimana Anda membuat tampilan dengan SNAPSHOT_MATERIALIZATION di SQL Server 2017?

36

SQL Server 2017 memiliki beberapa prosedur tersimpan baru:

  • sp_refresh_single_snapshot_view - param input untuk @view_name nvarchar (261), @rgCode int
  • sp_refresh_snapshot_views - param input untuk @rgCode int

Dan entri baru di sys.messages:

  • 10149 - Indeks yang memiliki SNAPSHOT_MATERIALIZATION tidak dapat dibuat pada tampilan '%. * Ls' karena definisi tampilan berisi tabel yang dioptimalkan memori.
  • 10642 - SNAPSHOT_MATERIALIZATION tidak dapat ditetapkan untuk indeks '%. * Ls' on '%. * Ls' karena hanya berlaku untuk indeks pada tampilan.
  • 10643 - SNAPSHOT_MATERIALIZATION tidak dapat ditetapkan untuk '%. * Ls' on '%. * Ls' karena hanya berlaku untuk indeks yang dikelompokkan pada tampilan.
  • 10648 - SNAPSHOT_MATERIALIZATION tidak dapat disetel untuk indeks terpartisi '%. * Ls' on '%. * Ls'.
  • 10649 - Indeks tidak tercakup '%. * Ls' tidak dapat dibuat di '%. * Ls' yang telah mengelompokkan indeks '%. * Ls' dengan SNAPSHOT_MATERIALIZATION.
  • 10650 - Refresh dari tampilan snapshot membutuhkan isolasi snapshot untuk diaktifkan pada database.
  • 3760 - Tidak dapat menurunkan indeks '%. * Ls' pada tampilan '%. * Ls' yang memiliki SNAPSHOT_MATERIALISASI.
  • 4524 - Tidak dapat mengubah tampilan '%. * Ls' karena ia memiliki materialisasi snapshot.
  • 4525 - Tidak dapat menggunakan petunjuk '% ls' pada tampilan '%. * Ls' yang memiliki materialisasi snapshot sebelum tampilan di-refresh.

Dan Acara Diperpanjang baru:

Tampilan foto Acara yang Diperpanjang

Jadi bagaimana kita bisa membuat tampilan snapshot terwujud? (Microsoft belum mendokumentasikannya, jelas.) Inilah inti dari hal-hal yang saya coba sejauh ini yang belum berhasil.

Brent Ozar
sumber

Jawaban:

55

Kamu tidak bisa Fitur ini dinonaktifkan pada 2017 RTM.


Yang mengatakan, Anda bisa ...

Menggunakan AdventureWorks:

CREATE VIEW dbo.TH
WITH SCHEMABINDING
AS
SELECT P.ProductID, COUNT_BIG(*) AS cbs
FROM Production.Product AS P
JOIN Production.TransactionHistory AS TH
    ON TH.ProductID = P.ProductID
GROUP BY P.ProductID;
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.TH (ProductID)
WITH (SNAPSHOT_MATERIALIZATION = ON);

Perubahan pada tabel yang mendasarinya tidak langsung tercermin dalam tampilan (seperti biasanya dengan SQL Server). Demikian juga, modifikasi data terhadap tabel yang mendasari tidak harus mempertahankan tampilan indeks snapshot.

Untuk menyegarkan konten tampilan, seseorang perlu memanggil salah satu prosedur tersimpan yang baru:

EXECUTE sys.sp_refresh_single_snapshot_view
    @view_name = N'dbo.TH',
    @rgCode = 0; -- don't know what this is for yet

Ini menghasilkan rencana eksekusi:

Rencana

Ini kemungkinan tidak akan bekerja untuk Anda, karena dibutuhkan tanda jejak yang tidak berdokumen, atau Anda perlu melakukan hal yang sangat tidak menyenangkan yang saya lakukan: menulis ke lokasi memori yang memegang bendera fitur (menggunakan debugger) untuk mengaktifkan fitur ini.

Jika Anda penasaran, flag fitur adalah byte at sqllang!g_featureSwitchesLangSvc+0x10f. Itu diperiksa selama sqllang!SpRefreshSingleSnapshotView.

Jika Anda ingin bermain bersama, dan sepenuhnya siap untuk menerima konsekuensi peretasan dalam kode SQL Server saat sedang berjalan, dan menggunakan fitur yang menurut Microsoft belum siap:

  1. Melampirkan debugger ke proses SQL Server 2017. Saya menggunakan WinDbg.
  2. Tetapkan breakpoint:

    bp sqllang!SpRefreshSingleSnapshotView
  3. Lanjutkan SQL Server menggunakan perintah Go ( g)

  4. Buat tampilan di atas, tetapi belum indeks cluster unik
  5. Jalankan sys.sp_refresh_single_snapshot_viewperintah di atas
  6. Ketika breakpoint terkena, langkah melalui sampai Anda melihat baris kode:

    cmp byte ptr [sqllang!g_featureSwitchesLangSvc+0x10f (00007fff`328dfbcf)],0

    Offset mungkin berbeda di build lain, misalnya pada 2017 RTM CU3 sqllang!g_featureSwitchesLangSvc+0x114

  7. Alamat memori di dalam tanda kurung mungkin berbeda. Gunakan yang Anda lihat.

  8. Gunakan perintah memori tampilan untuk melihat nilai saat ini di alamat memori yang Anda temukan:

    db 00007fff`328dfbcf L1
  9. Ini harus menunjukkan nol, menunjukkan bahwa fitur ini dinonaktifkan.

  10. Ubah nol menjadi satu, menggunakan perintah enter values ​​(lagi dengan alamat memori Anda):

    eb 00007fff`328dfbcf 1
  11. Nonaktifkan breakpoint dan lanjutkan menjalankan SQL Server.

  12. Fitur ini sekarang diaktifkan.
  13. Buat indeks berkerumun unik pada tampilan.
  14. Bermain-main.

Note SNAPSHOT_MATERIALIZATIONmemungkinkan kita untuk mewujudkan snapshot dari spesifikasi permintaan yang biasanya tidak dapat diindeks, misalnya menggunakan di bawah ini MAX:

CREATE VIEW dbo.TH2
WITH SCHEMABINDING
AS
SELECT TH.ProductID, MaxTransactionID = MAX(TH.TransactionID)
FROM Production.TransactionHistory AS TH
GROUP BY TH.ProductID;
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.TH2 (ProductID)
WITH (SNAPSHOT_MATERIALIZATION = ON);

Hasil:

Perintah berhasil diselesaikan.
Paul White mengatakan GoFundMonica
sumber