Kami memiliki database besar, sekitar 1TB, menjalankan SQL Server 2014 di server yang kuat. Semuanya bekerja dengan baik selama beberapa tahun. Sekitar 2 minggu yang lalu, kami melakukan pemeliharaan penuh, yang meliputi: Instal semua pembaruan perangkat lunak; membangun kembali semua indeks dan file DB kompak. Namun, kami tidak berharap bahwa pada tahap tertentu penggunaan CPU DB meningkat lebih dari 100% menjadi 150% ketika beban sebenarnya sama.
Setelah banyak pemecahan masalah, kami mempersempitnya menjadi kueri yang sangat sederhana, tetapi kami tidak dapat menemukan solusinya. Permintaannya sangat sederhana:
select top 1 EventID from EventLog with (nolock) order by EventID
Itu selalu memakan waktu sekitar 1,5 detik! Namun, permintaan serupa dengan "desc" selalu membutuhkan sekitar 0 ms:
select top 1 EventID from EventLog with (nolock) order by EventID desc
PTable memiliki sekitar 500 juta baris; EventID
adalah kolom indeks clustered primer (dipesan ASC
) dengan tipe data bigint (kolom Identity). Ada beberapa utas memasukkan data ke dalam tabel di atas (EventID lebih besar), dan ada 1 utas menghapus data dari bawah (EventID lebih kecil).
Dalam SMS, kami memverifikasi bahwa dua pertanyaan selalu menggunakan rencana eksekusi yang sama:
Pemindaian indeks berkelompok;
Diperkirakan dan nomor baris sebenarnya adalah 1;
Diperkirakan dan jumlah aktual eksekusi adalah 1;
Perkirakan biaya I / O adalah 8500 (Tampaknya tinggi)
Jika dijalankan secara berurutan, biaya Query adalah 50% sama untuk keduanya.
Saya memperbarui statistik indeks with fullscan
, masalahnya masih ada; Saya membangun kembali indeks itu lagi, dan masalahnya tampaknya sudah hilang selama setengah hari, tetapi kembali.
Saya menyalakan statistik IO dengan:
set statistics io on
kemudian jalankan dua pertanyaan secara berurutan dan temukan info berikut:
(Untuk kueri pertama, yang lambat)
Tabel 'PTable'. Pindai hitungan 1, bacaan logis 407670, bacaan fisik 0, bacaan baca depan 0, bacaan logis lob 0, bacaan fisik lob 0, bacaan baca lob depan 0.
(Untuk kueri kedua, yang cepat)
Tabel 'PTable'. Pindai hitungan 1, bacaan logis 4, bacaan fisik 0, bacaan baca depan 0, bacaan logis lob 0, bacaan fisik lob 0, bacaan baca lob depan 0.
Perhatikan perbedaan besar dalam pembacaan logis. Indeks digunakan dalam kedua kasus.
Fragmentasi indeks dapat menjelaskan sedikit, tetapi saya percaya dampaknya sangat kecil; dan masalahnya tidak pernah terjadi sebelumnya. Bukti lain adalah jika saya menjalankan kueri seperti:
select * from EventLog with (nolock) where EventID=xxxx
Bahkan jika saya menetapkan xxxx ke EventID terkecil di tabel, kueri selalu kilat.
Kami memeriksa dan tidak ada masalah penguncian / pemblokiran.
Catatan: Saya baru saja mencoba menyederhanakan masalah di atas. "PTable" sebenarnya "EventLog"; yang PID
adalah EventID
.
Saya mendapatkan hasil pengujian yang sama tanpa NOLOCK
petunjuk.
Adakah yang bisa membantu?
Paket eksekusi permintaan yang lebih rinci dalam XML sebagai berikut:
https://www.brentozar.com/pastetheplan/?id=SJ3eiVnob
https://www.brentozar.com/pastetheplan/?id=r1rOjVhoZ
Saya tidak berpikir itu penting untuk memberikan pernyataan membuat tabel. Ini adalah database lama dan telah berjalan dengan sangat baik untuk waktu yang lama hingga pemeliharaan. Kami telah melakukan banyak penelitian sendiri dan mempersempitnya ke info yang disediakan dalam pertanyaan saya.
Tabel dibuat secara normal dengan EventID
kolom sebagai kunci utama, yang merupakan identity
kolom tipe bigint
. Saat ini, saya kira masalahnya adalah dengan fragmentasi indeks. Tepat setelah indeks dibangun kembali, masalah tampaknya hilang selama setengah hari; tapi mengapa ia kembali begitu cepat ...?