Bagaimana saya bisa tahu MENGAPA memasukkan pada tabel tertentu lambat?

29

Saya tahu bahwa INSERT pada tabel SQL bisa lambat karena sejumlah alasan:

  • Keberadaan INSERT TRIGGER ada di atas meja
  • Banyak kendala yang dipaksakan yang harus diperiksa (biasanya kunci asing)
  • Halaman terpecah dalam indeks berkerumun ketika baris dimasukkan di tengah tabel
  • Memperbarui semua indeks non-cluster terkait
  • Memblokir dari aktivitas lain di atas meja
  • IO yang buruk menulis waktu respons
  • ... apa pun yang saya lewatkan?

Bagaimana saya bisa tahu mana yang bertanggung jawab dalam kasus spesifik saya? Bagaimana saya bisa mengukur dampak dari pemisahan halaman vs pembaruan indeks non-cluster vs yang lainnya?

Saya memiliki proc tersimpan yang menyisipkan sekitar 10.000 baris sekaligus (dari tabel temp), yang membutuhkan waktu sekitar 90 detik per 10k baris. Itu sangat lambat, karena menyebabkan spids lain mati.

Saya telah melihat rencana eksekusi, dan saya melihat tugas INSERT CLUSTERED INDEX dan semua INDEKS PENCARIAN dari pencarian FK, tetapi masih tidak memberi tahu saya pasti mengapa itu memakan waktu begitu lama. Tidak ada pemicu, tetapi tabel memang memiliki beberapa FKeys (yang tampaknya diindeks dengan benar).

Ini adalah database SQL 2000.

BradC
sumber
Apakah Anda memiliki ekspansi otomatis diaktifkan pada file data Anda? Itu dapat menyebabkan masalah kinerja dengan konfigurasi default.
Larry Coleman
Apakah kita berbicara tentang menggunakan profiler? msdn.microsoft.com/en-us/library/ms187929.aspx
Incognito
@ Larry: File data memiliki ruang kosong yang signifikan, jadi saya tidak percaya pertumbuhan file data adalah masalah. Bagus untuk ditambahkan ke daftar "hal-hal yang harus diperiksa".
BradC
@ user210: Membuat profil penyelesaian pernyataan hanya menunjukkan kepada saya bahwa butuh waktu 90 detik, itu tidak memberi tahu saya MENGAPA. Kecuali ada acara lain yang menurut Anda akan lebih jitu.
BradC

Jawaban:

10

Beberapa hal yang dapat Anda lihat ...

Kurangi ukuran batch dari 10.000 menjadi sesuatu yang lebih kecil, seperti 2000 atau 1000 (Anda tidak mengatakan seberapa besar ukuran baris Anda).

Coba nyalakan Statistik IO untuk melihat seberapa banyak IO yang diambil oleh FK.

Apa yang menunggu disebabkan oleh saat penyisipan itu terjadi (master.dbo.sysprocesses)?

Mari kita mulai dari sini dan lihat ke mana kita pergi.

mrdenny
sumber
2
Menurunkan ukuran kumpulan memang membantu (1000 rekaman membutuhkan ~ 25 detik). Itu kemungkinan menjadi "solusi" kami saat ini. Saya akan melihat apakah saya dapat menentukan Statistik IO dan menunggu (pekerjaan dijalankan berdasarkan permintaan oleh klien ketika mereka memiliki file untuk diproses, jadi saya tidak selalu dapat memprediksi kapan pekerjaan itu benar-benar akan berjalan).
BradC
7

Brad,

Anda harus memeriksa statistik tunggu untuk permintaan Anda. Dengan SQL2000 Anda bisa menggunakan sintaks DBCC SQLPERF ("waitstats") untuk mendapatkan detail tersebut.

SQLRockstar
sumber
6

Saya bisa mengatakan apa yang saya cari ketika menganalisis kinerja kueri. Mungkin itu membantu.

  • menganalisis rencana eksekusi permintaan dan memeriksa pemindaian indeks, pemindaian tabel, penggunaan fungsi convert_implicit untuk tipe data sql, paralelisme.
  • jalankan kueri dengan SET STATISTIK IO ON dan SET STATISTICS TIME ON untuk melihat waktu eksekusi dan baca / tulis io untuk setiap sisipan.
  • lihat waktu tunggu dari proses sys untuk spid sesi Anda.
  • jalankan profiler dan pilih templat standar. pilih berikut: Statistik kinerja (jika diulangi maka rencana Anda dikompilasi berkali-kali - tidak baik), RPC: selesai, SQL: batchcompleted dan SQL: batchstarting. Menambahkan kepada mereka kolom rowcounts untuk melihat secara tepat jumlah baris dalam batch. Saring hasil untuk hanya melihat kueri Anda.
  • akhirnya kumpulkan penghitung Page Life Expectancy dari windows perfmon dan jika di bawah 300 (5 menit) maka SQL memiliki memori rendah. Kumpulkan juga penghitung disk: panjang antrian disk , Waktu Disk (drive file data Anda), Waktu Disk (drive file Log Anda) untuk melihat apakah ada tekanan pada disk.
yrushka
sumber
5

Coba gunakan:

SET STATISTICS IO ON

dan

SET STATISTICS PROFILE ON

STATISTIK IO

Dapat berguna dalam memberi tahu Anda tabel mana yang paling banyak melakukan pemindaian tabel, pembacaan logis & pembacaan fisik (saya menggunakan ketiganya untuk fokus pada bagian mana dari rencana kueri yang paling membutuhkan penyetelan)

PROFIL STATISTIK

Terutama akan mengembalikan rencana kueri dalam format tabular, Anda kemudian dapat melihat kolom IO dan CPU untuk berapa biayanya paling banyak dalam kueri (apakah itu pemindaian tabel pada tabel temp Anda vs jenis yang dilakukannya untuk dimasukkan ke dalam Anda kunci berkerumun, dll ...)

Andrew Bickerton
sumber