Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Peningkatan tempdb di SQL Server 2019

Saya telah membuat rekomendasi yang sama tentang tempdb sejak saya mulai bekerja dengan SQL Server lebih dari 15 tahun yang lalu, ketika saya bekerja dengan pelanggan yang menjalankan versi 2000. Intinya:buat beberapa file data yang berukuran sama, dengan otomatis yang sama -pengaturan pertumbuhan, aktifkan bendera jejak 1118 (dan mungkin 1117), dan kurangi penggunaan tempdb Anda. Dari sisi pelanggan, ini adalah batas dari apa yang dapat dilakukan*, hingga SQL Server 2019.

*Ada beberapa rekomendasi coding tambahan yang Pam Lahoud bahas dalam postingannya yang sangat informatif, TEMPDB – Files and Trace Flags and Updates, Astaga!

Yang menurut saya menarik adalah, setelah sekian lama, tempdb masih menjadi masalah. Tim SQL Server telah membuat banyak perubahan selama bertahun-tahun untuk mencoba dan mengurangi masalah, tetapi penyalahgunaan terus berlanjut. Adaptasi terbaru oleh tim SQL Server adalah memindahkan tabel sistem (metadata) untuk tempdb ke In-Memory OLTP (alias memori yang dioptimalkan). Beberapa informasi tersedia di catatan rilis SQL Server 2019, dan ada demo dari Bob Ward dan Conor Cunningham selama hari pertama keynote PASS Summit. Pam Lahoud juga melakukan demo singkat di sesi umum PASS Summit-nya. Sekarang setelah CTP 3.2 2019 keluar, saya pikir mungkin ini saatnya untuk melakukan sedikit pengujian sendiri.

Penyiapan

Saya telah menginstal SQL Server 2019 CTP 3.2 di mesin virtual saya, yang memiliki memori 8GB (memori server maks diatur ke 6 GB) dan 4 vCPU. Saya membuat empat (4) file data tempdb, masing-masing berukuran 1GB.

Saya memulihkan salinan WideWorldImporters dan kemudian membuat tiga prosedur tersimpan (definisi di bawah). Setiap prosedur tersimpan menerima input tanggal, dan mendorong semua baris dari Sales.Order dan Sales.OrderLines untuk tanggal tersebut ke objek sementara. Di Sales.usp_OrderInfoTV objeknya adalah variabel tabel, di Sales.usp_OrderInfoTT objeknya adalah tabel sementara yang ditentukan melalui SELECT ... INTO dengan nonclustered ditambahkan setelahnya, dan di Sales.usp_OrderInfoTTALT objeknya adalah tabel sementara yang telah ditentukan sebelumnya yang kemudian diubah memiliki kolom tambahan. Setelah data ditambahkan ke objek sementara, ada pernyataan SELECT terhadap objek yang bergabung ke tabel Sales.Customers.

 /* Buat prosedur tersimpan */ GUNAKAN [WideWorldImporters]; GO DROP PROCEDURE JIKA ADA Sales.usp_OrderInfoTV GO CREATE PROCEDURE Sales.usp_OrderInfoTV @OrderDate TANGGAL AS MULAI DECLARE @OrdersInfo TABLE ( OrderID INT, OrderLineID INT, CustomerID INT, StockItemID INT, Quantity DECIMAL, UnitPrice; INSERT INTO @OrdersInfo ( OrderID, OrderLineID, CustomerID, StockItemID, Quantity, UnitPrice, OrderDate) PILIH o.OrderID, ol.OrderLineID, o.CustomerID, ol.StockItemID, ol.Quantity, ol.UnitPrice, OrderDate DARI Penjualan. INNER JOIN Sales.OrderLines ol PADA o.OrderID =ol.OrderID WHERE o.OrderDate =@OrderDate; PILIH o.OrderID, c.CustomerName, SUM (o.Quantity), SUM (o.UnitPrice) FROM @OrdersInfo o GABUNG Sales.Customers c ON o.CustomerID =c.CustomerID GROUP OLEH o.OrderID, c.CustomerName; SELESAI PROSEDUR DROP JIKA ADA Sales.usp_OrderInfoTT GO BUAT PROSEDUR Sales.usp_OrderInfoTT @OrderDate TANGGAL AS MULAI PILIH o.OrderID, ol.OrderLineID, o.CustomerID, ol.StockItemID, ol.orderinfoUniantity, ol. Penjualan.Pesanan o INNER JOIN Penjualan.OrderLines OL PADA o.OrderID =ol.OrderID WHERE o.OrderDate =@OrderDate; PILIH o.OrderID, c.CustomerName, SUM (o.Quantity), SUM (o.UnitPrice) DARI #temporderinfo o JOIN Sales.Customers c ON o.CustomerID =c.CustomerID GROUP OLEH o.OrderID, c.CustomerName END GO JATUHKAN PROSEDUR JIKA ADA Sales.usp_OrderInfoTTALT BUAT PROSEDUR BUAT Sales.usp_OrderInfoTTALT @OrderDate TANGGAL AS MULAI CREATE TABLE #temporderinfo ( OrderID INT, OrderLineID INT, CustomerID INT, StockItemID INT, Quantity INT, UnitPrice(18,2)); INSERT INTO #temporderinfo ( OrderID, OrderLineID, CustomerID, StockItemID, Quantity, UnitPrice) PILIH o.OrderID, ol.OrderLineID, o.CustomerID, ol.StockItemID, ol.Quantity, ol.UnitPrice FROM Sales.Orders atau INNER JOIN OrderLines ol ON o.OrderID =ol.OrderID WHERE o.OrderDate =@OrderDate; PILIH o.OrderID, c.CustomerName, SUM (o.Quantity), SUM (o.UnitPrice) DARI #temporderinfo o JOIN Sales.Customers c ON o.CustomerID c.CustomerID GROUP OLEH o.OrderID, c.CustomerName END GO / * Buat tabel untuk menyimpan data pengujian */ GUNAKAN [WideWorldImporters]; PERGI CREATE TABLE [dbo].[PerfTesting_Tests] ( [TestID] INT IDENTITY(1,1), [TestName] VARCHAR (200), [TestStartTime] DATETIME2, [TestEndTime] DATETIME2 ) PADA [PRIMARY]; PERGI BUAT TABEL [dbo].[PerfTesting_WaitStats] ( [TestID] [int] NOT NULL, [CaptureDate] [datetime] NOT NULL DEFAULT (sysdatetime()), [WaitType] [nvarchar](60) NOT NULL, [Wait_S] [desimal](16, 2) NULL, [Resource_S] [desimal](16, 2) NULL, [Signal_S] [desimal](16, 2) NULL, [WaitCount] [bigint] NULL, [Persentase] [desimal] (5, 2) NULL, [AvgWait_S] [desimal](16, 4) NULL, [AvgRes_S] [desimal](16, 4) NULL, [AvgSig_S] [desimal](16, 4) NULL ) ON [PRIMARY]; GO /* Aktifkan Query Store (pengaturan pengujian, tidak persis seperti yang saya sarankan untuk produksi) */ USE [master]; PERGI ALTER DATABASE [WideWorldImporters] SET QUERY_STORE =AKTIF; PERGI ALTER DATABASE [WideWorldImporters] SET QUERY_STORE ( OPERATION_MODE =READ_WRITE, CLEANUP_POLICY =(STALE_QUERY_THRESHOLD_DAYS =30), DATA_FLUSH_INTERVAL_SECONDS =600, INTERVAL_LENGTH_MINUTES =10, AUMIZE_QUE_SODE_TOCAUM_QUE_STOR =10, AUMIZE_QUE_SODE_MANUTES_SODE PERGI

Pengujian

Perilaku default untuk SQL Server 2019 adalah metadata tempdb tidak dioptimalkan memori, dan kami dapat mengonfirmasi ini dengan memeriksa sys.configurations:

 SELECT * FROM sys.configurations WHERE configuration_id =1589;

Untuk ketiga prosedur tersimpan kami akan menggunakan sqlcmd untuk menghasilkan 20 utas bersamaan yang menjalankan salah satu dari dua file .sql yang berbeda. File .sql pertama, yang akan digunakan oleh 19 utas, akan menjalankan prosedur dalam satu lingkaran 1000 kali. File .sql kedua, yang hanya akan memiliki satu (1) utas, akan menjalankan prosedur dalam satu lingkaran 3000 kali. File juga menyertakan TSQL untuk menangkap dua metrik yang menarik:durasi total dan statistik tunggu. Kami akan menggunakan Query Store untuk merekam durasi rata-rata prosedur.

 /* Contoh file .sql pertama yang memanggil SP 1000 kali */ SET NOCOUNT ON; PERGI GUNAKAN [WideWorldImporters]; PERGI MENYATAKAN @StartDate TANGGAL; MENYATAKAN @MaxDate TANGGAL; MENYATAKAN @Tanggal TANGGAL; MENYATAKAN @Counter INT =1; PILIH @TanggalMulai =MIN(TanggalPesanan) DARI [WideWorldImporters].[Penjualan].[Pesanan]; PILIH @MaxDATE =MAX(TanggalPesanan) DARI [WideWorldImporters].[Penjualan].[Pesanan]; SET @Tanggal =@TanggalMulai; SAAT @Counter <=1000 BEGIN EXEC [Penjualan].[usp_OrderInfoTT] @Date; JIKA @Tanggal <=@MaxDate MULAI SET @Tanggal =TANGGAL(HARI, 1, @Tanggal); AKHIR LAIN MULAI SET @Tanggal =@TanggalMulai; AKHIR SET @Penghitung =@Penghitung + 1; END GO /* Contoh file .sql kedua yang memanggil SP 3000 kali dan menangkap total durasi dan statistik tunggu */ SET NOCOUNT ON; PERGI GUNAKAN [WideWorldImporters]; PERGI MENYATAKAN @StartDate TANGGAL; MENYATAKAN @MaxDate TANGGAL; MENYATAKAN TANGGAL @TANGGAL; MENYATAKAN @Counter INT =1; MENYATAKAN @TestID INT; DECLARE @TestName VARCHAR(200) ='Eksekusi usp_OrderInfoTT - Tabel Sistem Berbasis Disk'; MASUKKAN KE [WideWorldImporters].[dbo].[PerfTesting_Tests] ([TestName]) NILAI (@TestName); PILIH @TestID =MAX(TestID) DARI [WideWorldImporters].[dbo].[PerfTesting_Tests]; PILIH @TanggalMulai =MIN(TanggalPesanan) DARI [WideWorldImporters].[Penjualan].[Pesanan]; PILIH @MaxDATE =MAX(TanggalPesanan) DARI [WideWorldImporters].[Penjualan].[Pesanan]; SET @Tanggal =@TanggalMulai; JIKA ADA (PILIH * FROM [tempdb].[sys].[objects] WHERE [name] =N'##SQLskillsStats1') DROP TABLE [##SQLskillsStats1]; JIKA ADA (PILIH * FROM [tempdb].[sys].[objects] WHERE [name] =N'##SQLskillsStats2') DROP TABLE [##SQLskillsStats2]; PILIH [wait_type], [waiting_tasks_count], [wait_time_ms], [max_wait_time_ms], [signal_wait_time_ms] INTO ##SQLskillsStats1 DARI sys.dm_os_wait_stats; /* atur waktu mulai */ UPDATE [WideWorldImporters].[dbo].[PerfTesting_Tests] SET [TestStartTime] =SYSDATETIME() WHERE [TestID] =@TestID; SAAT @Counter <=3000 BEGIN EXEC [Penjualan].[usp_OrderInfoTT] @Date; JIKA @Tanggal <=@MaxDate MULAI SET @Tanggal =TANGGAL(HARI, 1, @Tanggal); AKHIR LAIN MULAI SET @Tanggal =@TanggalMulai; AKHIR SET @Penghitung =@Penghitung + 1 AKHIR /* atur waktu berakhir */ UPDATE [WideWorldImporters].[dbo].[PerfTesting_Tests] SET [TestEndTime] =SYSDATETIME() WHERE [TestID] =@TestID; SELECT [wait_type], [waiting_tasks_count], [wait_time_ms], [max_wait_time_ms], [signal_wait_time_ms] INTO ##SQLskillsStats2 DARI sys.dm_os_wait_stats; DENGAN [DiffWaits] AS (SELECT -- Menunggu yang tidak ada di snapshot pertama [ts2].[wait_type], [ts2].[wait_time_ms], [ts2].[signal_wait_time_ms], [ts2].[waiting_tasks_count] FROM [##SQLskillsStats2] AS [ts2] KIRI OUTER JOIN [##SQLskillsStats1] AS [ts1] ON [ts2].[wait_type] =[ts1].[wait_type] WHERE [ts1].[wait_type] IS NULL DAN [ts2 ].[wait_time_ms]> 0 UNION SELECT -- Perbedaan antara menunggu di kedua snapshot [ts2].[wait_type], [ts2].[wait_time_ms] - [ts1].[wait_time_ms] AS [wait_time_ms], [ts2].[ signal_wait_time_ms] - [ts1].[signal_wait_time_ms] AS [signal_wait_time_ms], [ts2].[waiting_tasks_count] - [ts1].[waiting_tasks_count] AS [waiting_tasks_count] FROM [##SQLskillsStats2] SEBAGAI [#OUTER2] JOLEFT SQLskillsStats1] AS [ts1] ON [ts2].[wait_type] =[ts1].[wait_type] WHERE [ts1].[wait_type] IS NOT NULL AND [ts2].[waiting_tasks_count] - [ts1].[waiting_tasks_coun t]> 0 DAN [ts2].[wait_time_ms] - [ts1].[wait_time_ms] > 0), [Menunggu] AS (PILIH [tipe_tunggu], [waktu_waktu_md] / 1000.0 AS [Menunggu], ([waktu_waktu_ms] - [signal_wait_time_ms]) / 1000.0 AS [Sumber Daya], [signal_wait_time_ms] / 1000.0 AS [Sinyal], [ waiting_tasks_count] AS [WaitCount], 100.0 * [wait_time_ms] / SUM ([wait_time_ms]) OVER() AS [Percentage], ROW_NUMBER() OVER(ORDER BY [wait_time_ms] DESC) AS [RowNum] FROM [DiffWaits] WHERE [wait_type ] NOT IN ( -- Jenis menunggu ini hampir 100% tidak pernah menjadi masalah dan karenanya -- disaring untuk menghindari hasil yang tidak sesuai. N'BROKER_EVENTHANDLER', N'BROKER_RECEIVE_WAITFOR', N'BROKER_TASK_STOP', N'BROKER_TO_FLUSH' , N'BROKER_TRANSMITTER', N'CHECKPOINT_QUEUE', N'CHKPT', N'CLR_AUTO_EVENT', N'CLR_MANUAL_EVENT', N'CLR_SEMAPHORE', N'CXUESUMER', N'DBMIRROR_DBM_EVENT', N'DBMIRROR_EVENT'SERQUE_MIRROR_EVENT' , N'DBMIRRORING_CMD', N'DIRTY_PAGE_POLL ', N'DISPATCHER_QUEUE_SEMAPHORE', N'EXECSYNC', N'FSAGENT', N'FT_IFTS_SCHEDULER_IDLE_WAIT', N'FT_IFTSHC_MUTEX', N'HADR_CLUSAPI_CALL', N'HADR_FILESTREAM', N'KHADR_FILESTREAM_IOMGR_IOCOM_IOMGR_IO ', N'HADR_WORK_QUEUE', N'KSOURCE_WAKEUP', N'LAZYWRITER_SLEEP', N'LOGMGR_QUEUE', N'MEMORY_ALLOCATION_EXT', N'ONDEMAND_TASK_QUEUE', N'PARALLEL_REDO_DRAIN_WORKER', N'PARLOG_REDO_PAR', N'PARALLEL_REDO_DRAIN_WORKER', N'PARLOG ', N'PARALLEL_REDO_WORKER_WAIT_WORK', N'PREEMPTIVE_XE_GETTARGETSTATE', N'PWAIT_ALL_COMPONENTS_INITIALIZED', N'PWAIT_DIRECTLOGCONSUMER_GETNEXT', N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP', N'QDS_ASYNC_QUEUE', N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP', N'QDS_SHUTDOWN_QUEUE', N'REDO_THREAD_PENDING_WORK', N'REQUEST_FOR_DEADLOCK_SEARCH ', N'RESOURCE_QUEUE', N'SERVER_IDLE_CHECK', N'SLEEP_BPOOL_FL USH', N'SLEEP_DBSTARTUP', N'SLEEP_DCOMSTARTUP', N'SLEEP_MASTERDBREADY', N'SLEEP_MASTERMDREADY', N'SLEEP_MASTERUPGRADED', N'SLEEP_MSDBSTARTUP', N'SLEEP_SYSTEMTASK', N'SLEEP', N'SLEEP_SYSTEMTASK', N'SLE N'F'HTTP_ACCEPT', N'SOS_WORK_DISPATCHER', N'SP_SERVER_DIAGNOSTICS_SLEEP', N'SQLTRACE_BUFFER_FLUSH', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP', N'SQLTRACE_WAIT_ENTRIES', N'WAITS_WN'F'WAIT_ENTRIES', N'WAIT_FOR' (WAIT_XTP_HOST_WAIT', N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG', N'WAIT_XTP_CKPT_CLOSE', N'XE_DISPATCHER_JOIN', N'XE_DISPATCHER_WAIT', N'XE_TIMER_EVENT' ).[WideSID_Pelayan].[WideSID_EVENT' ) [WideSTID_EVENT' ) [WideSID_EVENT' ) [WideSTID_EVENT' ) [WideSID_EVENT' ) [WideS. , [Wait_S] , [Resource_S] , [Signal_S] , [WaitCount] , [Percentage] , [AvgWait_S] , [AvgRes_S] , [AvgSig_S] ) SELECT @TestID, [W1].[wait_type] AS [WaitType], CAST ([W1].[Menunggu] SEBAGAI DESIMA L (16, 2)) AS [Wait_S], CAST ([W1].[ResourceS] AS DECIMAL (16, 2)) AS [Resource_S], CAST ([W1].[SignalS] AS DECIMAL (16, 2) ) AS [Signal_S], [W1].[WaitCount] AS [WaitCount], CAST ([W1].[Persentase] AS DECIMAL (5, 2)) SEBAGAI [Persentase], CAST (([W1].[WaitS] / [W1].[WaitCount]) AS DECIMAL (16, 4)) AS [AvgWait_S], CAST (([W1].[ResourceS] / [W1].[WaitCount]) AS DECIMAL (16, 4)) AS [AvgRes_S], CAST (([W1].[SignalS] / [W1].[WaitCount]) AS DECIMAL (16, 4)) AS [AvgSig_S] FROM [Menunggu] SEBAGAI [W1] INNER JOIN [Menunggu] SEBAGAI [ W2] AKTIF [W2].[RowNum] <=[W1].[RowNum] GROUP BY [W1].[RowNum], [W1].[wait_type], [W1].[WaitS], [W1].[ ResourceS], [W1].[SignalS], [W1].[WaitCount], [W1].[Persentase] MEMILIKI SUM ([W2].[Persentase]) - [W1].[Persentase] <95; -- ambang persentase GO -- Pembersihan JIKA ADA (PILIH * FROM [tempdb].[sys].[objects] WHERE [name] =N'##SQLskillsStats1') DROP TABLE [##SQLskillsStats1]; JIKA ADA (PILIH * FROM [tempdb].[sys].[objects] WHERE [name] =N'##SQLskillsStats2') DROP TABLE [##SQLskillsStats2]; PERGI

Contoh file baris perintah:

Hasil

Setelah menjalankan file baris perintah yang menghasilkan 20 utas untuk setiap prosedur tersimpan, pemeriksaan total durasi untuk 12.000 eksekusi setiap prosedur menunjukkan hal berikut:

 SELECT *, DATEDIFF(SECOND, TestStartTime, TestEndTime) AS [TotalDuration] FROM [dbo].[PerfTesting_Tests] ORDER BY [TestID];

Prosedur tersimpan dengan tabel sementara (usp_OrderInfoTT dan usp_OrderInfoTTC) membutuhkan waktu lebih lama untuk diselesaikan. Jika kita melihat kinerja kueri individual:

 SELECT [qsq].[query_id], [qsp].[plan_id], OBJECT_NAME([qsq].[object_id]) AS [ObjectName], [rs].[count_executions], [rs].[last_execution_time] , [rs].[avg_duration], [rs].[avg_logical_io_reads], [qst].[query_sql_text] FROM [sys].[query_store_query] [qsq] GABUNG [sys].[query_store_query_text] [qst] AKTIF [qsq] .[query_text_id] =[qst].[query_text_id] GABUNG [sys].[query_store_plan] [qsp] AKTIF [qsq].[query_id] =[qsp].[query_id] GABUNG [sys].[query_store_runtime_stats] [rs] ON [qsp].[plan_id] =[rs].[plan_id] WHERE ([qsq].[object_id] =OBJECT_ID('Sales.usp_OrderInfoTT')) ATAU ([qsq].[object_id] =OBJECT_ID('Sales. usp_OrderInfoTV')) ATAU ([qsq].[object_id] =OBJECT_ID('Sales.usp_OrderInfoTTALT')) ORDER BY [qsq].[query_id], [rs].[last_execution_time];

Kita dapat melihat bahwa SELECT … INTO untuk usp_OrderInfoTT membutuhkan waktu rata-rata sekitar 28 md (durasi di Query Store disimpan dalam mikrodetik), dan hanya membutuhkan waktu 9 md ketika tabel sementara telah dibuat sebelumnya. Untuk variabel tabel, INSERT mengambil rata-rata lebih dari 22 ms. Menariknya, kueri SELECT membutuhkan waktu lebih dari 1 md untuk tabel sementara, dan sekitar 2,7 md untuk variabel tabel.

Pemeriksaan data statistik tunggu menemukan wait_type yang sudah dikenal, PAGELATCH*:

 SELECT * FROM [dbo].[PerfTesting_WaitStats] ORDER BY [TestID], [Percentage] DESC;

Perhatikan bahwa kita hanya melihat PAGELATCH* menunggu tes 1 dan 2, yang merupakan prosedur dengan tabel sementara. Untuk usp_OrderInfoTV, yang menggunakan variabel tabel, kita hanya melihat SOS_SCHEDULER_YIELD menunggu. Harap diperhatikan: Ini sama sekali tidak menyiratkan bahwa Anda harus menggunakan variabel tabel alih-alih tabel sementara , juga tidak menyiratkan bahwa Anda tidak memiliki PAGELATCH menunggu dengan variabel tabel. Ini adalah skenario yang dibuat-buat; Saya sangat merekomendasikan Anda menguji dengan kode ANDA untuk melihat wait_types apa yang muncul.

Sekarang kita akan mengubah instance untuk menggunakan tabel yang dioptimalkan memori untuk metadata tempdb. Ada dua cara yang dapat dilakukan, melalui perintah ALTER SERVER CONFIGURATION, atau dengan menggunakan sp_configure. Karena setelan ini adalah opsi lanjutan, jika Anda menggunakan sp_configure, Anda harus mengaktifkan opsi lanjutan terlebih dahulu.

ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA =ON;GO

Setelah perubahan ini, perlu untuk memulai ulang ke instance. (CATATAN:Anda dapat mengubahnya kembali menjadi TIDAK menggunakan tabel yang dioptimalkan memori, Anda hanya perlu memulai ulang instance lagi.) Setelah memulai ulang, jika kita memeriksa sys.configurations lagi, kita dapat melihat tabel metadata dioptimalkan untuk memori:

Setelah mengeksekusi file baris perintah lagi, total durasi untuk 21.000 eksekusi setiap prosedur menunjukkan hal berikut (perhatikan bahwa hasil diurutkan oleh prosedur tersimpan untuk perbandingan yang lebih mudah):

Jelas ada peningkatan kinerja untuk usp_OrderInfoTT dan usp_OrderInfoTTC , dan sedikit peningkatan kinerja untuk usp_OrderInfoTV. Mari kita periksa durasi kueri:

Untuk semua kueri, durasi kueri hampir sama, kecuali untuk peningkatan durasi INSERT saat tabel dibuat sebelumnya, yang sama sekali tidak terduga. Kami memang melihat perubahan menarik dalam statistik menunggu:

Untuk usp_OrderInfoTT, SELECT … INTO dijalankan untuk membuat tabel sementara. Penantian berubah dari PAGELATCH_EX dan PAGELATCH_SH menjadi saja PAGELATCH_EX dan SOS_SCHEDULER_YIELD. Kami tidak lagi melihat PAGELATCH_SH menunggu.

Untuk usp_OrderInfoTTC, yang membuat tabel sementara dan kemudian menyisipkan, PAGELATCH_EX dan PAGELATCH_SH menunggu tidak lagi muncul, dan kita hanya melihat SOS_SCHEDULER_YIELD menunggu.

Terakhir, untuk OrderInfoTV, waktu tunggunya konsisten – hanya SOS_SCHEDULER_YIELD, dengan total waktu tunggu yang hampir sama.

Ringkasan

Berdasarkan pengujian ini, kami melihat peningkatan dalam semua kasus, secara signifikan untuk prosedur tersimpan dengan tabel sementara. Ada sedikit perubahan untuk prosedur variabel tabel. Sangat penting untuk diingat bahwa ini adalah satu skenario, dengan uji beban kecil. Saya sangat tertarik untuk mencoba tiga skenario yang sangat sederhana ini, untuk mencoba dan memahami apa yang paling diuntungkan dari membuat metadata tempdb dioptimalkan memori. Beban kerja ini kecil dan berjalan untuk waktu yang sangat terbatas – sebenarnya saya memiliki hasil yang lebih bervariasi dengan lebih banyak utas, yang perlu ditelusuri di pos lain. Manfaat terbesarnya adalah, seperti halnya semua fitur dan fungsionalitas baru, pengujian itu penting. Untuk fitur ini, Anda ingin memiliki dasar performa saat ini untuk membandingkan metrik seperti Permintaan Batch/Detik dan statistik tunggu setelah mengoptimalkan memori metadata.

Pertimbangan Tambahan

Menggunakan OLTP Dalam Memori memerlukan grup file dari tipe DATA MEMORY OPTIMIZED. Namun, setelah mengaktifkan MEMORY_OPTIMIZED TEMPDB_METADATA, tidak ada grup file tambahan yang dibuat untuk tempdb. Selain itu, tidak diketahui apakah tabel yang dioptimalkan memori tahan lama (SCHEMA_AND_DATA) atau tidak (SCHEMA_ONLY). Biasanya ini dapat ditentukan melalui sys.tables (durability_desc), tetapi tidak ada hasil untuk tabel sistem yang terlibat saat menanyakan ini di tempdb, bahkan saat menggunakan Koneksi Administrator Khusus. Anda memang memiliki kemampuan untuk melihat indeks nonclustered untuk tabel yang dioptimalkan memori. Anda dapat menggunakan kueri berikut untuk melihat tabel mana yang dioptimalkan memori di tempdb:

 PILIH * FROM tempdb.sys.dm_db_xtp_object_stats x GABUNG tempdb.sys.objects o ON x.object_id =o.object_id GABUNG tempdb.sys.schemas s PADA o.schema_id =s.preschema_id;
 Kemudian, untuk tabel mana pun, jalankan sp_helpindex, misalnya:

EXEC sys.sp_helpindex N'sys.sysobjvalues';

Perhatikan bahwa jika itu adalah indeks hash (yang memerlukan perkiraan BUCKET_COUNT sebagai bagian dari pembuatan), deskripsinya akan menyertakan "hash nonclustered".


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara mendapatkan Catatan Berbeda dari tabel di SQL Server - Tutorial SQL Server / TSQL 112

  2. Pernyataan ALTER TABLE bertentangan dengan batasan CHECK di SQL Server - Tutorial SQL Server / TSQL Bagian 89

  3. Cara Mengembalikan Daftar Tipe Data di SQL Server (T-SQL)

  4. Arsitektur SQL Server AlwaysOn (Availability Group) dan Instalasi Langkah demi Langkah -3 Manual Fail Over Steps

  5. Batalkan pivot dengan nama kolom