Penggunaan CPU tinggi pada server SQL - Permintaan lambat [ditutup]


11

MS SQL Server kami menggunakan sekitar 95% daya CPU.

Setelah server (perangkat keras) restart, atau SQL-Service restart, penggunaannya adalah 0% dan perlahan-lahan meningkat selama 1-3 hari. Tergantung berapa banyak yang digunakan.

Ketika lebih dari 80%, setiap permintaan sangat lambat.

Situs web kami berurusan dengan banyak pertanyaan besar, sehingga beberapa di antaranya memakan waktu 45-60 detik. Setelah restart (penggunaan CPU kurang dari 80%), dibutuhkan 11-20 detik untuk Permintaan yang sama.


Bagaimana saya bisa memperbaikinya? Saya telah membaca secara online bahwa masker afinitas dapat menyesuaikan penggunaan CPU, tetapi pengaturan Afinitas dinonaktifkan. Saya tidak bisa mengubahnya. Apakah ini karena saya hanya punya 1 prosesor?

Ada banyak trik yang harus dilakukan dengan kueri itu sendiri, tetapi situs web dan layanan kami cukup besar, dan ada terlalu banyak perubahan.

Kebanyakan dari mereka sudah dioptimalkan dengan cukup baik.


Saya tidak dapat terus me-restart SQL-Service, meskipun hanya membutuhkan waktu 2 detik, karena kami memiliki layanan alarm yang memungkinkan orang untuk memanggil dan merekam pesan, grup yang dipilih kemudian akan dipanggil dan mendengar pesan yang direkam.

Sistem ini digunakan oleh ratusan tim Pencarian dan Penyelamatan, dan jika SQL-Service restart selama alarm, itu akan berakhir dan orang yang memanggilnya tidak akan diberitahu.


Saya telah mencari di semua tempat, tetapi tidak menemukan apa pun kecuali hal-hal tentang "Masker Afinitas", yang tidak dapat saya ubah.

Pasti ada cara untuk menghapus cache CPU, tanpa menghentikan permintaan saat ini ... kan?


SQL: Microsoft SQL Server 11.0.2100.60
OS: Windows Server 2012 x64
Processor: 2.30 GHz
RAM: 4.00 GB

Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Paul White 9

Jawaban:


7

Ini kemungkinan besar, tetapi Anda mungkin ingin melihat pengaturan parametrization yang dipaksakan. Jika Anda melihat sejumlah besar paket kueri saat kinerjanya buruk, kueri Anda tidak di-cache seperti yang Anda harapkan dan kueri membutuhkan waktu lama untuk memindai melalui cache untuk melihat apakah ada rencana yang sudah digunakan. Jika mengosongkan cache memecahkan masalah ini, Anda mungkin ingin melihat ke dalam mengubah pengaturan parameterisasi paksa. Anda dapat menghapus cache menggunakan:

DBCC FREEPROCCACHE

Anda dapat memeriksa untuk melihat apa pengaturan parametrization paksa jika membersihkan cache bekerja dengan:

SELECT name
     , is_parameterization_forced
  FROM sys.databases;

Ini mungkin diatur ke 0, default. Jika mereka mau, Anda dapat mengaturnya menjadi benar dengan melakukan:

ALTER DATABASE [database_name] SET PARAMETERIZATION FORCED;

Ini harus dilakukan di lingkungan pengembang terlebih dahulu dan lihat apakah ini berdampak negatif pada database dengan cara lain. Itu dapat dikembalikan menggunakan:

ALTER DATABASE [database_name] SET PARAMETERIZATION SIMPLE;

5
Perhatikan bahwa membebaskan cache prosedur sebenarnya dapat menyebabkan lonjakan besar dalam CPU - karena semua permintaan sekarang harus mengkompilasi ulang rencana eksekusi mereka.
Aaron Bertrand

18

Afinitas tidak "menyesuaikan penggunaan CPU" (misalnya dalam kasus Anda membuat CPU melakukan lebih sedikit pekerjaan), itu memungkinkan Anda untuk mematikan CPU (mungkin untuk membuatnya tersedia untuk contoh lain pada mesin yang sama) atau mengatur CPU untuk bantuan dengan I / O saja. Bahkan jika Anda memiliki banyak CPU, Anda tidak akan dapat menggunakan yang pertama untuk membantu tujuan Anda, dan tidak mungkin bagi kami untuk menebak yang terakhir karena kami tidak tahu apa yang mendorong penggunaan CPU Anda begitu tinggi. Bisa jadi karena pengindeksan yang sangat buruk, kompilasi berlebihan, UDF skalar berlimpah, meronta-ronta I / O, siapa tahu? (Dan alasan I / O bisa menjadi penyebabnya adalah bahwa jika database Anda lebih besar dari 3 GB atau lebih, itu akan terus-menerus harus menukar data masuk dan keluar dari memori buffer pool, dan ini akan berdampak pada CPU.)

Cache CPU, juga, adalah lubang kelinci Anda tidak perlu turun. Saya sangat ragu CPU Anda meronta-ronta pada 95% karena masalah dengan cache CPU Anda.

Untuk membantu mempersempit sumber tekanan CPU, dan dengan asumsi Anda menggunakan prosedur tersimpan, Anda dapat melihat permintaan diagnostik ini dari Glenn Berry ( bersumber dari sini ) - pastikan Anda menjalankannya dalam konteks database yang tepat:

-- Top Cached SPs By Total Worker time (SQL Server 2012). 
-- Worker time relates to CPU cost  (Query 44) (SP Worker Time)

SELECT TOP (25) 
  p.name AS [SP Name], 
  qs.total_worker_time AS [TotalWorkerTime], 
  qs.total_worker_time/qs.execution_count AS [AvgWorkerTime], 
  qs.execution_count, 
  ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time, GETDATE()), 0) 
    AS [Calls/Second],
  qs.total_elapsed_time, 
  qs.total_elapsed_time/qs.execution_count AS [avg_elapsed_time], 
  qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK)
ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);

-- This helps you find the most expensive cached stored procedures from a CPU perspective
-- You should look at this if you see signs of CPU pressure

Jika Anda tidak menggunakan prosedur tersimpan, maka contoh dari John Samson ini dapat membantu mengisolasi kueri ad hoc ( bersumber dari sini ):

SELECT TOP (25)
    qs.sql_handle,
    qs.execution_count,
    qs.total_worker_time AS Total_CPU,
    total_CPU_inSeconds = --Converted from microseconds
    qs.total_worker_time/1000000,
    average_CPU_inSeconds = --Converted from microseconds
    (qs.total_worker_time/1000000) / qs.execution_count,
    qs.total_elapsed_time,
    total_elapsed_time_inSeconds = --Converted from microseconds
    qs.total_elapsed_time/1000000,
    st.text,
    qp.query_plan
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS apply sys.dm_exec_query_plan (qs.plan_handle) AS qp
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);

Anda juga dapat melihat sp_WhoIsActive Adam Machanic , prosedur tersimpan yang dapat dengan cepat menganalisis semua permintaan yang sedang berjalan, dan memungkinkan Anda untuk mengurutkannya sesuai keinginan Anda (misalnya dalam kasus Anda @sort_order = '[CPU] DESC').

Namun, hal pertama yang akan saya lakukan - terutama jika ini benar-benar penting untuk tim pencarian dan penyelamatan - adalah membeli perangkat keras yang lebih baik. Anda harus memiliki lebih banyak CPU dan lebih banyak RAM untuk melayani aplikasi Anda. Anda juga benar-benar membutuhkan ketersediaan tinggi yang lebih baik (mis. Pengelompokan, mirroring atau Ketersediaan Grup). Tidak ada alasan bahwa reboot mesin fisik harus membuat aplikasi Anda sepenuhnya offline - kami memiliki solusi yang lebih baik untuk masalah itu. Dan akhirnya, saya kira "server" ini hanya memiliki satu drive disk spinny. Ini berarti bahwa semua I / O - dari OS, dari file data SQL Server, file log, tempdb, dll. Semua melalui pengontrol tunggal dan berbagi aktivitas baca / tulis pada satu drive. Dapatkan lebih banyak disk. Dapatkan SSD jika / di mana Anda bisa. Gunakan RAID dan coba sebarkan I / O sebanyak mungkin.

Itu semua mengatakan, melempar perangkat keras pada masalah tidak akan menjadi satu-satunya bagian dari perbaikan. Anda perlu mengisolasi apa yang menyebabkan penggunaan CPU berlebih dan kemudian menyerang masalah-masalah itu tidak peduli perangkat keras apa yang Anda gunakan.

Lihat juga pertanyaan StackOverflow ini untuk beberapa ide lain:

/programming/945063/how-do-i-find-out-what-is-hammering-my-sql-server


0

Saran berikut adalah 'suntikan dalam gelap' karena saya tidak dapat melihat kode aktual.

Pertama adalah bahwa SP mungkin membuka kursor dan membiarkannya terbuka. Baca tentang Kursor, terutama Tutup dan Alokasikan. Seseorang mungkin menutup, tetapi tidak menghilangkan kursor. Perilaku mungkin telah berubah karena peningkatan, 2012 mungkin memperlakukan kursor sisa berbeda dari 2008 R2.

Kedua, mungkin ada kunci meja yang tidak dibersihkan. Sekali lagi, saya berada di kejauhan sehingga saya tidak bisa mengatakannya, tetapi itu akan menyarankan bahwa seseorang membuat tabel temp global setelah 'mulai transaksi', dan entah tidak ada 'transaksi akhir' dijalankan atau prosedur tersimpan gagal meninggalkan terkunci meja menempati ruang di tempdb.

Apakah Anda menggunakan WinLink? Sesuatu tentang hal ini terdengar agak asing.


-4

Anda harus memiliki mekanisme caching di tempat seperti memcached untuk meningkatkan kinerja


Tapi ini tidak akan mengubah penggunaan CPU pada SQL-Server, kan? Itu hanya akan membuat pertanyaan berjalan lebih cepat di situs web, dan mungkin ada masalah jika ada sesuatu yang diubah dalam tabel sementara orang lain menggunakan hasil memcached dari tabel yang sama, kan?
Levi Johansen

@Levi jika Anda menyimpan hasil kueri di suatu tempat di tingkat tengah maka kueri tidak mengenai database (kecuali ketika Anda perlu menyegarkan cache).
Aaron Bertrand

1
Jika CPU juga tinggi ketika tidak ada orang di situs web, maka cukup jelas caching hal-hal tingkat web tidak akan membantu. Memcached adalah alat yang hebat, tetapi bukan pengganti untuk orang yang kompeten untuk duduk dan mencari tahu apa yang dilakukan server ketika seharusnya tidak melakukan apa-apa.
TomTom
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.