Itu bisa terjadi bahwa sejumlah kecil data mencapai batas tertentu di SQL Server untuk memaksa rencana lain atau sesuatu seperti itu. Ini bukan tidak mungkin. Tetapi fakta bahwa disk Anda tampaknya sedang dalam tugas membawa saya ke kesimpulan lain.
Ada 2 alasan dasar yang mungkin untuk memperlambat Anda.
- Anda memutakhirkan sistem Anda dan menyalakannya kembali
- Anda memuat banyak data di dalamnya
Mari kita lihat bagian No. 1
Mungkin konfigurasi SQL Server Anda mungkin rusak. Ini dapat menyebabkan masalah serius terkait kecepatan Server Anda dan penggunaan disk.
Silakan periksa pada contoh pertama pengaturan server dasar Anda. Mereka pengaturan dasar max server memory
, affinity I/O mask
, affinity mask
dan max degree of parallelism
. Anda mungkin perlu mengaktifkan opsi lanjutan menggunakan show advanced options
.
Berikut ini skrip lengkap:
-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'
Bandingkan hasilnya dengan nilai yang Anda dokumentasikan pada langkah instalasi Anda. Apakah mereka masih sama?
Mungkin ada banyak alasan mengapa server Anda berperilaku sangat aneh. Saya biasanya bertaruh, bahwa Anda max server memory
salah. Ini akan menyebabkan SQL Server Anda bertukar halaman data secara permanen. Dia tidak bisa menyimpan semuanya dalam ingatannya. Ini berarti dia perlu membaca halaman dari disk, memperbaruinya, menulisnya kembali secara instan. Jika pembaruan lain datang dan menggunakan halaman yang sama untuk pembaruan, itu tidak dapat dibaca dari memori. Sebaliknya server perlu membacanya lagi dari disk. Hanya bertukar ...
Masalah lain dapat menjadi afinitas tinggi pada disk atau proses. Jika Anda menggunakan Server bersama (SQL Server + layanan lain) dengan disk khusus untuk SQL Server (yang mungkin jarang terjadi, tetapi bisa jadi), ini bisa menjadi masalah Anda. Server Anda biasanya memiliki misalnya 3 cpus untuk proses dan satu untuk I / O. 12 cpus lainnya digunakan untuk layanan lain. Dalam hal ini topeng afinitas Anda salah dan menggunakan misalnya konfigurasi otomatis. Ini berarti Server Anda menggunakan semua 16 core untuk proses dan I / O secara dinamis. Jika Anda memiliki proses besar yang sedang berjalan, mereka dapat menempatkan beban yang sangat besar pada disk, yang mungkin tidak ditangani. Tetapi pada kenyataannya, saya tidak percaya bahwa ini adalah kasus Anda. Akan lebih cepat (bahkan jika hanya sedikit) jika ini akan berlaku, tetapi kasing Anda lambat.
Masalah lain mungkin adalah tingkat paralelisme yang terlalu tinggi. Yang berarti Anda memiliki terlalu banyak utas yang menganggur di satu bagian dari kueri. Ini juga dapat menyebabkan pelambatan besar jika paralelisme tidak berfungsi seperti yang diharapkan. Tapi ini tidak akan menjelaskan I / O tinggi Anda secara total.
Sekarang mari kita lihat bagian no 2 juga
Anda memuat banyak baris ke dalam sistem Anda. Bahkan jika ini adalah pekerjaan biasa, itu bisa meningkatkan batas di mana rencana kueri Anda meningkat. Bisa jadi ini kasus bahwa sisipan Anda dalam kombinasi dengan SQL Server menghasilkan perilaku ini.
Anda menyebutkan bahwa Anda sudah mencoba memigrasi indeks Anda ke disk lain, yang sepertinya membantu. Ini dapat terjadi hanya karena Anda membagi beban pada dua disk yang berbeda.
Mungkin saja indeks Anda retak, bahwa rencana Anda retak atau bahwa statistik Anda baru saja kedaluwarsa.
1. mari kita periksa statistik pembaruan terakhir
Anda dapat melakukan ini secara manual melalui antarmuka untuk setiap elemen statistik tunggal. Itu akan menyebalkan. Atau Anda dapat mencoba kode ini:
SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes
Ini akan memberi Anda informasi lengkap tentang setiap indeks (dan tumpukan) dan statistik di belakangnya. Bahkan jika Anda menjalankannya, sp_updatestats
itu tidak berarti bahwa statistik diperbarui. Bagian ketika pembaruan cukup rumit, bahkan jika Anda menjalankan sp_updatestats
atau bahkan jika auto update statistics
diaktifkan, statistik tidak akan diperbarui tepat waktu. Berikut adalah beberapa poin tepi, ketika pembaruan diperlukan / dibuat:
- Meja kosong mendapat satu atau lebih baris
- Tabel dengan lebih dari 500 baris memperbarui 20% + 500 baris tambahan dan penyisipan terjadi setelahnya
- Ketika 500 baris diubah dalam tabel yang menampung kurang dari 500 baris
Ini berarti, statistik Anda mungkin kedaluwarsa walaupun Anda menjalankan pembaruan.
Anda dapat melihat permintaan di atas. Jika Anda menemukan beberapa statistik yang cukup lama di beberapa tabel, Anda mungkin ingin menjalankan pembaruan statistik manual untuk tabel ini:
UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN
Setelah itu, Anda mungkin ingin memberikan tendangan ke server Anda untuk membuang semua rencana lama.
DBCC FREEPROCCACHE
Jika Anda hanya ingin membersihkan semua cache, Anda mungkin ingin menjalankan ini sebagai gantinya:
DBCC FREESYSTEMCACHE ('ALL')
Ini akan membersihkan semua cache, bukan hanya cache rencana. Saya biasanya memperingatkan, untuk menggunakan ini pada server produksi dalam fase produksi. Tetapi karena server Anda tidak berfungsi saat ini, Anda tidak dapat terlalu membahayakan mereka. Mungkin memperlambat selama beberapa detik mungkin 1-2 menit karena dia perlu membangun kembali semua cache, tetapi setelah itu dia harus menjalankan dengan rencana yang benar.
Alasan lain adalah indeks yang benar-benar terfragmentasi. Ini dapat diperiksa di seluruh server menggunakan pernyataan ini:
SELECT *
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)
Jika fragmentasi sangat tinggi, Anda mungkin perlu mengatur ulang (fragmentasi <20%) atau membangun kembali total (> 20%). Ini mungkin membutuhkan lebih banyak tekanan pada disk Anda dan menyebabkan masalah. Di sisi lain, jika indeksnya seburuk itu, mungkin pada akhirnya akan lebih membantu daripada merugikan.
Selain dua alasan itu, mungkin masih ada masalah ketiga
Mungkin server Anda dikonfigurasi mungkin, Anda belum mengubah kode apa pun saat ini, hanya menambahkan beberapa baris. Semua statistik diperbarui dan semua cache dibangun kembali. Semua indeks Anda ditata ulang sesuai dengan kebutuhan Anda, tetapi tetap saja - tidak ada yang berhasil. Mungkin saja Anda mencapai batas memori yang tersedia dalam proses Anda. Mungkin Anda membutuhkan lebih banyak. Anda cukup memeriksa apakah ada proses yang mencoba mendapatkan lebih banyak memori daripada yang Anda miliki.
Anda dapat memeriksanya menggunakan perintah ini:
SELECT * FROM sys.dm_exec_query_memory_grants
Ini akan memberi Anda daftar semua sesi yang menghabiskan memori. Mungkin ada beberapa permintaan yang masih menunggu untuk mendapatkan memori. Pertanyaan-pertanyaan itu dapat dengan mudah disaring. Semua sesi ada di mana granted_memory_kb IS NULL
. Ini adalah sesi yang meminta memori tetapi tidak mendapatkannya. Hal lain dapat berupa memori yang diberikan yang mungkin rendah. Anda dapat membandingkan kolom requested_memory_kb
dengan granted_memory_kb
. Diminta menunjukkan berapa banyak memori yang diperlukan untuk menjalankan proses secara optimal sementara diberikan menunjukkan memori yang memungkinkan untuk proses. Jika suatu proses membutuhkan 2GB untuk dijalankan tetapi hanya mendapat 2MB ... Anda mungkin mendapatkannya sendiri. ;-)
Cara lain adalah dengan memeriksa RESSOURCE_SEMAPHORE
:
SELECT * FROM sys.dm_exec_query_resource_semaphore
Anda dapat melihat waiter_count
dan grantee_count
. Jika pelayan di atas 0, Anda memiliki tekanan pada memori Anda, yang dapat menyebabkan swapping dan dapat menyebabkan tekanan disk terlihat oleh Anda di perfmon.