Penurunan kinerja SQL Server mendadak

13

Saya memiliki SQL Server 2005 yang telah menjadi tak terduga akhir-akhir ini, dan saya menggaruk-garuk kepala mengapa. Pertanyaan yang dieksekusi dalam hitungan detik mengubah rencana dan mengambil menit (meluangkan waktu dalam pemindaian tabel penuh atau spool indeks). Sekarang hal pertama dan yang paling jelas adalah, statistiknya usang sehingga pengoptimal menjadi bingung tetapi saya yakin ini tidak terjadi - pertama karena data yang mendasarinya tidak berubah secara signifikan (misalnya menambahkan data satu hari di atas data setahun sudah ada dalam tabel) dan kedua karena Statistik Buat Otomatis dan Statistik Pembaruan Otomatis keduanya benar. Namun optimizer adalah semakin bingung; menjalankan SQL di Tuning Advisor memberi saya banyak CREATE STATISTICSpernyataan multi-kolom yang sepertinya memperbaikinya (sampai bit berikutnya dari SQL yang nakal).

Adakah ide strategi yang dapat saya gunakan untuk melakukan pendekatan terhadap penyebab masalah ini? Adakah alasan mengapa statistik "normal" tidak mencukupi?

Gayus
sumber

Jawaban:

8

Jika top wait Anda adalah SOS_SCHEDULER_YIELD, maka tampaknya Anda memiliki tekanan pada CPU. Tapi ini bisa jadi akibat dari sesuatu yang lain, seperti desain Anda tidak lagi memadai untuk pertanyaan Anda. Saya tahu Anda mengatakan bahwa Anda hanya menambahkan data satu hari, tetapi Anda bisa mencapai titik kritis.

Bagaimana pertanyaan Anda dikeluarkan? Apakah SQL dinamis? Apakah Anda menggunakan prosedur tersimpan? Apakah Anda menggunakan sp_executesql? Apakah mungkin Anda memiliki case sniffing parameter? Seperti apa desain db Anda? Apa hubungan PK dan FK?

Apakah Anda memiliki contoh rencana yang bagus? Jika Anda dapat menentukan paket yang baik, Anda bisa menggunakan panduan paket untuk memaksa permintaan untuk mengeksekusi dengan cara tertentu.

Bisakah Anda memberi contoh rencana yang baik menjadi buruk?

Terakhir, ambil salinan sp_whoIsActive ( http://whoisactive.com/ ) dari Adam Machanic dan gunakan itu untuk menentukan lebih banyak tentang kueri yang sedang berjalan. Dan jika Anda ingin dapat menangkap output dari sp_whoIsActive, buka di sini http://www.littlekendra.com/2011/02/01/whoisactive/

SQLRockstar
sumber
Ini adalah aplikasi pihak ketiga, saya tidak memiliki kontrol atas skema atau SQL-nya, yang cukup mengerikan, banyak pertanyaan parameter (misalnya where col=(cast @var...)) dan @varmungkin '%'. Saya baru saja mewarisinya satu atau dua minggu yang lalu, dan pada dasarnya harus tetap berfungsi sampai diganti. Terima kasih untuk tautannya, saya akan berputar.
Gayus
Penantian terbesar berikutnya SOS_SCHEDULER_YIELDadalah CXPACKETdan sp_configure "max degree of parallelism", 1untuk saat ini - telah mengetuk kedua masalah di kepala. Terima kasih!
Gayus
+1 untuk tautan ke sp_whoIsActive
Jeff
8

Dari MSDN :

" Sisipkan Operasi yang Terjadi pada Menanjak atau Menurun Kolom Kunci Statistik pada kolom kunci naik atau turun, seperti IDENTITY atau kolom timestamp waktu-nyata, mungkin memerlukan pembaruan statistik yang lebih sering daripada yang dilakukan pengoptimal query. Memasukkan operasi menambahkan nilai baru ke kolom naik atau turun. Jumlah baris yang ditambahkan mungkin terlalu kecil untuk memicu pembaruan statistik. Jika statistik tidak mutakhir dan kueri pilih dari baris yang paling baru ditambahkan, statistik saat ini tidak akan memiliki perkiraan kardinalitas untuk nilai-nilai baru ini. menghasilkan perkiraan kardinalitas yang tidak akurat dan kinerja kueri yang lambat.

Misalnya, permintaan yang memilih dari tanggal pesanan penjualan terbaru akan memiliki perkiraan kardinalitas yang tidak akurat jika statistik tidak diperbarui untuk menyertakan perkiraan kardinalitas untuk tanggal pesanan penjualan terbaru.

Setelah Operasi Pemeliharaan Pertimbangkan untuk memperbarui statistik setelah melakukan prosedur perawatan yang mengubah distribusi data, seperti memotong tabel atau melakukan penyisipan massal sebagian besar baris. Ini dapat menghindari penundaan di masa depan dalam pemrosesan permintaan sementara permintaan menunggu pembaruan statistik otomatis. "

Anda dapat menggunakan "EXEC sp_updatestats" dari waktu ke waktu di sistem Anda (dijadwalkan beberapa waktu) atau menggunakan fungsi STATS_DATE pada semua objek dan melihat kapan statistik mereka benar-benar diperbarui terakhir kali dan jika ada terlalu banyak waktu sejak saat itu, gunakan UPDATE STATISTIK untuk objek tertentu. Dalam pengalaman saya, bahkan dengan statistik Otomatis diaktifkan kami masih dipaksa untuk memperbarui statistik dari waktu ke waktu, karena operasi penyisipan yang tidak memicu pembaruan otomatis.

Untuk menambahkan kode pribadi saya (digunakan dalam pekerjaan mingguan yang membuat pernyataan dinamis untuk pembaruan statistik):

select distinct
        'update statistics [' + stats.SchemaName + '].[' + stats.TableName + ']'
            + case when stats.RowCnt > 50000 then ' with sample 30 percent;'
            else 
                ';' end
        as UpdateStatement
    from (
        select
            ss.name SchemaName,
            so.name TableName,
            so.id ObjectId,
            st.name AS StatsName, 
            STATS_DATE(st.object_id, st.stats_id) AS LastStatisticsUpdateDate
            , si.RowModCtr
            , (select case si2.RowCnt when 0 then 1 else si2.RowCnt end from sysindexes si2 where si2.id = si.id and si2.indid in (0,1)) RowCnt
        from sys.stats st
            join sysindexes si on st.object_id = si.id and st.stats_id = si.indid
            join sysobjects so on so.id = si.id and so.xtype = 'U' --user table
            join sys.schemas ss on ss.schema_id = so.uid
    ) stats
    where cast(stats.RowModCtr as float)/cast(stats.RowCnt as FLOAT)*100 >= 10 --more than 10% of the rows have changed
    or ( --update statistics that were not updated for more than 3 months (and rows no > 0)
        datediff(month, stats.LastStatisticsUpdateDate, getdate()) >= 3
        and stats.RowCnt > 0
    )

Di sini saya mendapatkan semua objek di mana statistik tidak diperbarui selama lebih dari 3 bulan atau sejak statistik terakhir diperbarui memiliki lebih dari 10% dari baris diubah.

Marian
sumber
Hmm, acara tunggu utama saya adalah SOS_SCHEDULER_YIELDtetapi saya tidak bisa mengatakan sekarang apakah itu karena rencana yang buruk, atau bahwa kotak ini (6 tahun, 2-prosesor, 4G RAM) benar-benar hanya kelebihan beban sekarang dan saya sudah melewati beberapa titik kritis.
Gayus
alih-alih hanya menjalankan kueri itu untuk membuat pernyataan UPDATE dan menjalankannya secara manual, Anda bisa menggunakan kursor berdasarkan pernyataan pilih itu untuk mengulang hasil yang dijalankan menggunakan panggilan ke sp_executesql - dengan cara itu Anda dapat menjalankannya secara otomatis (misalnya sebagai bagian dari rencana pemeliharaan semalam (atau periode tenang lainnya)).
David Spillett
@ David: ini yang saya lakukan di pekerjaan mingguan :). Saya baru saja memformatnya secara berbeda agar Gayus melihat output yang saya gunakan. Naskah awal terlalu jelek dan panjang. Terima kasih atas bantuan pemformatan! Dapatkah Anda mengirim saya ke tutorial pemformatan..karena saya tidak benar-benar tahu bagaimana membuat kode terlihat bagus di sini. Terima kasih!
Marian
ada tautan "bantuan format" pada layar "edit jawaban", dan sebagai ikon di kanan atas kotak jawaban awal pada halaman pertanyaan utama, yang mencantumkan sintaks penurunan harga yang didukung oleh situs-situs ini.
David Spillett
3
Statistik pembaruan otomatis sebenarnya dipicu pada 20% + 500 baris, bukan 10%.
mrdenny
3

Dugaan saya adalah bahwa satu atau lebih tabel Anda menjadi cukup besar sehingga mereka tidak mencapai 20% dari perubahan yang diperlukan untuk membantu menandai bahwa statistik saat ini basi sehingga Statistik Pembaruan Otomatis akan muncul, namun ada cukup pembaruan (atau sisipan ) bahwa memiliki statistik yang diperbarui akan banyak membantu. Saya menemukan hal yang sama baru-baru ini di lingkungan tertentu setelah memutakhirkan dari SQL 2000 ke SQL 2008.

Selain situs lain yang disebutkan dalam jawaban di atas, saya sarankan memeriksa sumber daya online berikut.

1) Red-Gate memiliki sejumlah ebook gratis yang tersedia untuk diunduh termasuk "SQL Server Statistics" oleh Holger Schmeling, di mana Anda akan menemukan kutipan berikut:

http://www.red-gate.com/our-company/about/book-store/

"tabel dengan lebih dari 500 baris setidaknya 20% dari data kolom harus diubah untuk membatalkan statistik yang tertaut"

2) SQL Sentry memiliki alat Plan Explorer gratis yang membantu melacak masalah dalam rencana SQL, seperti perkiraan terlalu banyak atau terlalu sedikit baris dibandingkan dengan jumlah aktual baris untuk tabel tertentu dalam kueri. Simpan saja rencana eksekusi yang sebenarnya dari SSMS dan kemudian berjalanlah melalui bagian-bagian berbeda dari rencana menggunakan Plan Explorer. Bukan berarti informasi tersebut tidak tersedia di SSMS menggunakan rencana eksekusi grafik, tetapi alat dari SQL Sentry membuatnya lebih mudah untuk dilihat.

http://www.sqlsentry.com/plan-explorer/sql-server-query-view.asp

3) Periksa sendiri tanggal pembaruan statistik untuk tabel di kueri yang paling Anda minati menggunakan STATS_DATE (), Anda dapat menemukan kueri cepat untuk mendapatkan statistik terlama menggunakan kueri yang ditemukan dalam diskusi berikut.

http://blog.sqlauthority.com/2010/01/25/sql-server-find-statistics-update-date-update-update-statistics/

Saya harap ini membantu!

Saya pikir Anda akan sangat menikmati buku dari Red-Gate!

-Jeff

Jeff
sumber
Terima kasih, saya akan bekerja melalui itu. Saya terutama seorang Oracle DBA yang telah mewarisi sistem ini (tho 'Saya tidak berprasangka terhadap SQL Server sama sekali, dari apa yang saya lihat sejak 2005 itu adalah platform yang sangat mampu, saya hanya tidak tahu dan saya tahu Oracle) .
Gayus