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

Tiga Kemenangan Kinerja SQL Server yang Mudah

Seperti yang diketahui DBA produksi veteran, Anda sering berada di bawah tekanan yang signifikan untuk mendiagnosis dan mengurangi masalah kinerja database secepat mungkin. Berikut adalah tiga hal yang mungkin dapat Anda manfaatkan, bergantung pada beban kerja dan infrastruktur Anda, untuk memberikan dampak positif yang sangat nyata pada kinerja database Anda.

Penyesuaian Indeks Toko Baris Dasar

Sebagian besar contoh SQL Server yang saya temui dalam karir saya memiliki beberapa peluang penyetelan indeks toko baris yang relatif mudah. Satu hal yang menyenangkan tentang penyetelan indeks penyimpanan baris adalah ia lebih sering berada di bawah kendali langsung Anda sebagai DBA, terutama dibandingkan dengan penyetelan kueri atau prosedur tersimpan, yang sering berada di bawah kendali pengembang atau vendor pihak ke-3.

Beberapa DBA enggan melakukan penyetelan indeks apa pun (terutama pada database pihak ke-3) karena mereka khawatir akan merusak sesuatu atau membahayakan dukungan vendor untuk database atau aplikasi. Jelas, Anda harus lebih berhati-hati dengan basis data pihak ke-3, dan mencoba menghubungi vendor sebelum membuat perubahan indeks sendiri, tetapi dalam beberapa situasi, Anda mungkin tidak memiliki alternatif lain yang layak (selain membuang perangkat keras dan penyimpanan yang lebih cepat pada masalah tersebut. ).

Anda dapat menjalankan beberapa kueri utama dari Kueri Informasi Diagnostik SQL Server saya untuk mendapatkan ide yang bagus jika Anda mungkin memiliki beberapa peluang penyetelan indeks yang mudah pada instans atau database Anda. Anda harus mewaspadai permintaan indeks yang hilang, peringatan indeks yang hilang, indeks non-clustered yang kurang digunakan atau tidak digunakan, dan kemungkinan peluang kompresi data.

Dibutuhkan beberapa pengalaman, penilaian yang baik, dan pengetahuan tentang beban kerja Anda untuk melakukan penyetelan indeks yang tepat. Sudah terlalu umum untuk melihat orang melakukan penyetelan indeks yang salah, dengan terburu-buru membuat banyak perubahan indeks tanpa melakukan analisis yang tepat.

Berikut adalah beberapa pertanyaan yang ingin saya gunakan, di tingkat basis data:

-- Missing Indexes for current database by Index Advantage  (Query 1) (Missing Indexes)
 
SELECT DISTINCT CONVERT(decimal(18,2), user_seeks * avg_total_user_cost * (avg_user_impact * 0.01)) AS [index_advantage], 
  migs.last_user_seek, mid.[statement] AS [Database.Schema.Table],
  mid.equality_columns, mid.inequality_columns, mid.included_columns,
  migs.unique_compiles, migs.user_seeks, migs.avg_total_user_cost, migs.avg_user_impact,
  OBJECT_NAME(mid.[object_id]) AS [Table Name], p.rows AS [Table Rows]
  FROM sys.dm_db_missing_index_group_stats AS migs WITH (NOLOCK)
  INNER JOIN sys.dm_db_missing_index_groups AS mig WITH (NOLOCK)
  ON migs.group_handle = mig.index_group_handle
  INNER JOIN sys.dm_db_missing_index_details AS mid WITH (NOLOCK)
  ON mig.index_handle = mid.index_handle
  INNER JOIN sys.partitions AS p WITH (NOLOCK)
  ON p.[object_id] = mid.[object_id]
  WHERE mid.database_id = DB_ID()
  AND p.index_id < 2 
  ORDER BY index_advantage DESC OPTION (RECOMPILE);
 
  ------
  -- Look at index advantage, last user seek time, number of user seeks to help determine source and importance
  -- SQL Server is overly eager to add included columns, so beware
  -- Do not just blindly add indexes that show up from this query!!!
 
  -- Find missing index warnings for cached plans in the current database  (Query 2) (Missing Index Warnings)
  -- Note: This query could take some time on a busy instance
 
  SELECT TOP(25) OBJECT_NAME(objectid) AS [ObjectName], 
                 cp.objtype, cp.usecounts, cp.size_in_bytes, query_plan
  FROM sys.dm_exec_cached_plans AS cp WITH (NOLOCK)
  CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp
  WHERE CAST(query_plan AS NVARCHAR(MAX)) LIKE N'%MissingIndex%'
  AND dbid = DB_ID()
  ORDER BY cp.usecounts DESC OPTION (RECOMPILE);
 
  ------
  -- Helps you connect missing indexes to specific stored procedures or queries
  -- This can help you decide whether to add them or not
  -- Possible Bad NC Indexes (writes >= reads)  (Query 3) (Bad NC Indexes)
 
  SELECT OBJECT_NAME(s.[object_id]) AS [Table Name], i.name AS [Index Name], i.index_id, 
  i.is_disabled, i.is_hypothetical, i.has_filter, i.fill_factor,
  s.user_updates AS [Total Writes], s.user_seeks + s.user_scans + s.user_lookups AS [Total Reads],
  s.user_updates - (s.user_seeks + s.user_scans + s.user_lookups) AS [Difference]
  FROM sys.dm_db_index_usage_stats AS s WITH (NOLOCK)
  INNER JOIN sys.indexes AS i WITH (NOLOCK)
  ON s.[object_id] = i.[object_id]
  AND i.index_id = s.index_id
  WHERE OBJECTPROPERTY(s.[object_id],'IsUserTable') = 1
  AND s.database_id = DB_ID()
  AND s.user_updates > (s.user_seeks + s.user_scans + s.user_lookups)
  AND i.index_id > 1 AND i.[type_desc] = N'NONCLUSTERED'
  AND i.is_primary_key = 0 AND i.is_unique_constraint = 0 AND i.is_unique = 0
  ORDER BY [Difference] DESC, [Total Writes] DESC, [Total Reads] ASC OPTION (RECOMPILE);
 
  ------
  -- Look for indexes with high numbers of writes and zero or very low numbers of reads
  -- Consider your complete workload, and how long your instance has been running
  -- Investigate further before dropping an index!
  -- Breaks down buffers used by current database by object (table, index) in the buffer cache  (Query 4) (Buffer Usage)
  -- Note: This query could take some time on a busy instance
  SELECT OBJECT_NAME(p.[object_id]) AS [Object Name], p.index_id, 
  CAST(COUNT(*)/128.0 AS DECIMAL(10, 2)) AS [Buffer size(MB)],  
  COUNT(*) AS [BufferCount], p.[Rows] AS [Row Count],
  p.data_compression_desc AS [Compression Type]
  FROM sys.allocation_units AS a WITH (NOLOCK)
  INNER JOIN sys.dm_os_buffer_descriptors AS b WITH (NOLOCK)
  ON a.allocation_unit_id = b.allocation_unit_id
  INNER JOIN sys.partitions AS p WITH (NOLOCK)
  ON a.container_id = p.hobt_id
  WHERE b.database_id = CONVERT(int, DB_ID())
  AND p.[object_id] > 100
  AND OBJECT_NAME(p.[object_id]) NOT LIKE N'plan_%'
  AND OBJECT_NAME(p.[object_id]) NOT LIKE N'sys%'
  AND OBJECT_NAME(p.[object_id]) NOT LIKE N'xml_index_nodes%'
  GROUP BY p.[object_id], p.index_id, p.data_compression_desc, p.[Rows]
  ORDER BY [BufferCount] DESC OPTION (RECOMPILE);
 
  ------
  -- Tells you what tables and indexes are using the most memory in the buffer cache
  -- It can help identify possible candidates for data compression

Menggunakan Daya Tahan Tertunda

Fitur daya tahan tertunda telah ditambahkan ke produk di SQL Server 2014, sehingga telah tersedia untuk beberapa waktu. Komit transaksi tahan lama yang tertunda bersifat asinkron dan melaporkan komit transaksi sebagai berhasil sebelum catatan log untuk transaksi sebenarnya ditulis ke subsistem penyimpanan. Transaksi tahan lama yang tertunda tidak benar-benar menjadi tahan lama sampai entri log transaksi di-flush ke disk.

Fitur ini tersedia di semua edisi SQL Server. Meskipun demikian, saya jarang melihatnya digunakan ketika saya melihat database klien. Ketahanan yang tertunda memang membuka kemungkinan kehilangan beberapa data, hingga seluruh buffer log dalam skenario terburuk (seperti yang dijelaskan oleh Paul Randal di sini), jadi jelas tidak sesuai untuk skenario RPO di mana sama sekali tidak ada kehilangan data yang dapat diterima.

Ketahanan tertunda mengurangi latensi transaksi karena tidak menunggu log IO selesai dan mengembalikan kontrol kembali ke klien, dan juga mengurangi penguncian dan pertikaian disk untuk transaksi bersamaan. Kedua manfaat ini sering kali memiliki efek yang sangat positif pada kueri dan kinerja aplikasi Anda dengan beban kerja tulis yang sangat berat.

Ketahanan yang tertunda paling sering membantu beban kerja jenis OLTP berat yang memiliki transaksi tulis kecil yang sangat sering di mana Anda melihat latensi tulis tingkat file tinggi dari sys.dm_io_virtual_file_stats pada file log transaksi dan/atau Anda melihat WRITELOG menunggu dari sys. dm_os_wait_stats.

Anda dapat dengan mudah memaksa SQL Server 2014 atau yang lebih baru untuk menggunakan daya tahan tertunda untuk semua transaksi (tanpa perubahan kode) dengan menjalankan perintah berikut:

ALTER DATABASE AdventureWorks2014 SET DELAYED_DURABILITY = FORCED;

Saya memiliki klien yang secara terprogram mengaktifkan dan menonaktifkan daya tahan tertunda pada waktu yang berbeda dalam sehari (seperti selama ETL terjadwal atau aktivitas pemeliharaan). Saya juga memiliki klien yang menggunakan daya tahan tertunda setiap saat karena mereka memiliki beban kerja yang sesuai dan toleransi risiko kehilangan data.

Akhirnya, saya memiliki klien yang tidak akan pernah mempertimbangkan untuk menggunakan daya tahan yang tertunda, atau tidak membutuhkannya dengan beban kerja mereka. Jika Anda menduga bahwa beban kerja Anda mungkin manfaat dari penggunaan daya tahan yang tertunda, tetapi Anda khawatir tentang kemungkinan kehilangan data, maka ada alternatif lain yang dapat Anda pertimbangkan.

Salah satu alternatif adalah fitur buffer log yang bertahan di SQL Server 2016 SP1, di mana Anda dapat membuat file log transaksi 20 MB kedua pada volume penyimpanan mode akses langsung (DAX) yang di-host di perangkat memori persisten NV-DIMM. File log transaksi tambahan ini digunakan untuk men-cache ekor log, dengan akses tingkat byte yang melewati tumpukan penyimpanan tingkat blok konvensional.

Jika Anda berpikir bahwa beban kerja Anda mungkin mendapat manfaat dari penggunaan fitur buffer log persisten, Anda dapat bereksperimen dengan menggunakan ketahanan tertunda sementara untuk melihat apakah ada manfaat kinerja yang sebenarnya dengan beban kerja Anda sebelum Anda menghabiskan uang untuk memori persisten NV-DIMM yang Anda perlu menggunakan fitur buffer log yang bertahan.

Memindahkan tempdb ke Penyimpanan Intel Optane DC P4800X

Saya telah sukses besar dengan beberapa klien baru-baru ini yang memindahkan file database tempdb mereka dari beberapa jenis penyimpanan lain ke drive logis yang didukung oleh beberapa kartu penyimpanan Intel Optane DC P4800X PCIe NVMe (dalam perangkat lunak RAID 1 array).

Kartu penyimpanan ini tersedia dalam kapasitas 375GB, 750GB, dan 1,5TB (walaupun kapasitas 1,5TB masih baru dan masih sulit ditemukan). Mereka memiliki latensi yang sangat rendah (jauh lebih rendah daripada semua jenis penyimpanan flash NAND), kinerja I/O acak yang sangat baik pada kedalaman antrean rendah (jauh lebih baik daripada penyimpanan flash NAND), dengan waktu respons baca yang konsisten di bawah beban kerja tulis yang sangat berat.

Mereka juga memiliki daya tahan tulis yang lebih tinggi daripada penyimpanan flash NAND perusahaan "intensif menulis", dan kinerjanya tidak menurun karena hampir penuh. Karakteristik ini membuat kartu ini sangat cocok untuk banyak beban kerja tempdb yang berat, terutama beban kerja OLTP yang berat dan situasi di mana Anda menggunakan RCSI di database pengguna Anda (yang menempatkan beban kerja penyimpanan versi yang dihasilkan pada tempdb).

Juga sangat umum untuk melihat latensi tulis tingkat file yang tinggi pada file data tempdb dari sys.dm_io_virtual_file_stats DMV, jadi memindahkan file data tempdb Anda ke penyimpanan Optane adalah salah satu cara untuk langsung mengatasi masalah itu, yang mungkin lebih cepat dan lebih mudah daripada konvensional penyetelan beban kerja.

Kemungkinan penggunaan lain untuk kartu penyimpanan Optane adalah sebagai rumah untuk file log transaksi Anda. Anda juga dapat menggunakan penyimpanan Optane dengan SQL Server versi lawas (selama OS dan perangkat keras Anda mendukungnya). Ini adalah alternatif yang memungkinkan untuk menggunakan daya tahan tertunda (yang memerlukan SQL Server 2014) atau menggunakan fitur buffer log yang bertahan (yang memerlukan SQL Server 2016 SP1).

Kesimpulan

Saya membahas tiga teknik untuk mencetak kemenangan kinerja cepat dengan SQL Server:

  • Penyetelan indeks penyimpanan baris konvensional berlaku untuk semua versi SQL Server, dan ini adalah salah satu alat terbaik di gudang senjata Anda.
  • Ketahanan tertunda tersedia di SQL Server 2014 dan yang lebih baru, dan bisa sangat bermanfaat dengan beberapa jenis beban kerja (dan persyaratan RPO). Buffer log yang bertahan tersedia di SQL Server 2016 SP1, dan memberikan manfaat yang sama seperti daya tahan yang tertunda, tanpa bahaya kehilangan data.
  • Memindahkan jenis file database tertentu ke penyimpanan Intel Optane dapat membantu meringankan masalah kinerja dengan tempdb atau dengan file log transaksi database pengguna. Anda dapat menggunakan penyimpanan Optane dengan SQL Server versi lawas, dan tidak diperlukan perubahan kode atau konfigurasi.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nilai acak untuk kolom DATETIME

  2. Bagaimana cara memindahkan tabel ke skema di T-SQL

  3. Memahami Ukuran Penyimpanan 'datetimeoffset' di SQL Server

  4. 4 Cara Mendapatkan Riwayat Pekerjaan SQL Server

  5. database terlampir hanya baca