Perusahaan saya menggunakan aplikasi yang memiliki masalah kinerja yang cukup besar. Ada beberapa masalah dengan database itu sendiri yang sedang dalam proses saya kerjakan, tetapi banyak masalah yang terkait aplikasi murni.
Dalam investigasi saya, saya menemukan bahwa ada jutaan query yang mengenai database SQL Server yang meminta tabel kosong. Kami memiliki sekitar 300 tabel kosong dan beberapa dari tabel tersebut dipertanyakan hingga 100-200 kali per menit. Tabel tidak ada hubungannya dengan area bisnis kami dan pada dasarnya adalah bagian dari aplikasi asli yang tidak dihapus oleh vendor ketika mereka dikontrak oleh perusahaan saya untuk menghasilkan solusi perangkat lunak bagi kami.
Terlepas dari kenyataan bahwa kami mencurigai log kesalahan aplikasi kami dibanjiri dengan kesalahan yang terkait dengan masalah ini, vendor meyakinkan kami bahwa tidak ada dampak kinerja atau stabilitas baik untuk aplikasi atau server database. Log kesalahan dibanjiri sejauh kita tidak dapat melihat lebih dari 2 menit kesalahan untuk melakukan diagnosa.
Biaya sebenarnya dari pertanyaan ini jelas akan rendah dalam hal siklus CPU dll. Tapi adakah yang bisa menyarankan apa efeknya pada SQL Server dan aplikasi? Saya akan curiga bahwa mekanisme pengiriman permintaan, konfirmasi, pemrosesan, pengembalian, dan penerimaan tanda terima oleh aplikasi itu sendiri akan berdampak pada kinerja.
Kami menggunakan SQL Server 2008 R2, Oracle Weblogic 11g untuk aplikasi.
@ Frisbee- Singkatnya, saya membuat tabel berisi querytext yang mengenai tabel-tabel kosong di basis data aplikasi, lalu menanyakannya untuk semua nama yang saya tahu kosong dan mendapat daftar yang sangat panjang. Hit tertinggi adalah pada 2,7 juta eksekusi selama 30 hari uptime, mengingat aplikasi ini umumnya digunakan pada jam 8 pagi - 6 sore sehingga angka-angka itu lebih terkonsentrasi pada jam operasional. Beberapa tabel, beberapa kueri, mungkin beberapa relavent via gabungan, beberapa tidak. Hit teratas (2,7 juta pada saat itu) adalah pemilihan sederhana dari satu tabel kosong dengan klausa di mana, tanpa gabungan. Saya mengharapkan pertanyaan yang lebih besar dengan bergabung ke tabel kosong mungkin termasuk pembaruan ke tabel tertaut, tetapi saya akan memeriksanya dan memperbarui pertanyaan ini secepatnya.
Pembaruan: Ada 1000 pertanyaan dengan jumlah eksekusi antara 1043 - 4622614 (lebih dari 2,5 bulan). Saya harus menggali lebih banyak untuk mengetahui kapan rencana cache berasal dari. Ini hanya untuk memberi Anda gambaran tentang tingkat pertanyaan. Sebagian besar cukup rumit dengan lebih dari 20 bergabung.
@ srutzky- ya saya percaya ada kolom tanggal terkait ketika rencana itu disusun sehingga akan menarik, jadi saya akan memeriksanya. Saya ingin tahu apakah batas utas menjadi faktor sama sekali ketika SQL Server duduk di kluster VMware? Segera menjadi Dell PE 730xD yang berdedikasi untungnya.
@Frisbee - Maaf atas tanggapan yang terlambat. Seperti yang Anda sarankan, saya menjalankan pilih * dari tabel kosong 10.000 kali lebih dari 24 utas menggunakan SQLQueryStress (jadi sebenarnya 240.000 iterasi) dan tekan 10.000 Permintaan Batch / detik segera. Kemudian saya berkurang menjadi 1000 kali lebih dari 24 utas dan mencapai kurang dari 4.000 Permintaan Batch / detik. Saya juga mencoba 10.000 iterasi dengan hanya 12 thread (jadi total iterasi 1.200) dan ini menghasilkan 6.505 Batch berkelanjutan / detik. Efek pada CPU sebenarnya terlihat, sekitar 5-10% dari total penggunaan CPU selama setiap pengujian berjalan. Jaringan menunggu dapat diabaikan (seperti 3ms dengan klien di workstation saya) tetapi dampak CPU ada di sana, yang cukup meyakinkan sejauh yang saya ketahui. Tampaknya bermuara pada penggunaan CPU dan sedikit file database IO yang tidak perlu. Total eksekusi / detik bekerja di bawah 3000, yang lebih dari produksi, namun saya menguji hanya satu dari puluhan pertanyaan seperti ini. Efek bersih dari ratusan kueri yang mengenai tabel kosong dengan kecepatan antara 300-4000 kali per menit karenanya tidak akan diabaikan ketika menyangkut waktu CPU. Semua pengujian dilakukan terhadap idle PE 730xD dengan dual flash array dan 256GB RAM, 12 core modern.
@ srutzky- pemikiran yang bagus. SQLQueryStress tampaknya menggunakan pooling koneksi secara default, tetapi saya telah melihat pula dan menemukan bahwa ya, kotak untuk pooling koneksi diperiksa. Perbarui untuk mengikuti
@ srutzky- Kumpulan koneksi tampaknya tidak diaktifkan pada aplikasi - atau jika itu, itu tidak berfungsi. Saya melakukan penelusuran profiler dan menemukan bahwa koneksi memiliki EventSubClass "1 - Nonpooled" untuk acara Login Audit.
RE: Connection Pooling- Memeriksa weblogics dan menemukan pooling koneksi diaktifkan. Berlari lebih banyak jejak terhadap hidup dan menemukan tanda-tanda pengumpulan tidak terjadi dengan benar / sama sekali:
Dan di sini adalah seperti apa ketika saya menjalankan permintaan tunggal tanpa bergabung dengan tabel yang dihuni; pengecualian berbunyi "Galat terkait jaringan atau contoh khusus terjadi saat membuat koneksi ke SQL Server. Server tidak ditemukan atau tidak dapat diakses. Pastikan nama instance sudah benar dan bahwa SQL Server dikonfigurasi untuk memungkinkan koneksi jarak jauh. (penyedia: Penyedia Pipa Bernama, kesalahan: 40 - Tidak dapat membuka koneksi ke SQL Server) "Perhatikan penghitung permintaan batch. Ping server selama waktu pengecualian dihasilkan menghasilkan respons ping yang sukses.
Pembaruan - dua pengujian berturut-turut berjalan, beban kerja yang sama (pilih * dariEmptyTable), pengumpulan diaktifkan / tidak diaktifkan. Penggunaan CPU sedikit lebih banyak dan banyak kegagalan dan tidak pernah melampaui permintaan batch 500 / detik. Pengujian menunjukkan 10.000 Batch / detik dan tidak ada kegagalan dengan pooling ON, dan sekitar 400 batch / detik maka banyak kegagalan karena pooling dinonaktifkan. Saya ingin tahu apakah kegagalan ini terkait dengan kurangnya ketersediaan koneksi?
@ srutzky- Pilih Hitungan (*) dari sys.dm_exec_connections;
Pooling diaktifkan: 37 secara konsisten, bahkan setelah tes beban berhenti
Pooling dinonaktifkan: 11-37 tergantung pada ada atau tidaknya pengecualian
pada SQLQueryStress yaitu: ketika palung tersebut muncul pada
grafik Batch / sec, pengecualian terjadi pada SQLQueryStress, dan
jumlah koneksi turun menjadi 11, kemudian secara bertahap kembali ke 37 ketika bets mulai memuncak dan pengecualian tidak terjadi. Sangat, sangat menarik.
Koneksi maksimum pada kedua instance uji / langsung ditetapkan pada default 0.
Telah memeriksa log aplikasi dan tidak dapat menemukan masalah konektivitas, hanya ada beberapa menit logging yang tersedia karena jumlah besar dan ukuran kesalahan yaitu: banyak kesalahan jejak stack. Seorang kolega pada dukungan aplikasi menyarankan bahwa sejumlah besar kesalahan HTTP terjadi terkait dengan konektivitas. Tampaknya berdasarkan ini, bahwa untuk beberapa alasan aplikasi tidak mengumpulkan koneksi secara benar dan sebagai hasilnya, server berulang kali kehabisan koneksi. Saya akan melihat log aplikasi lebih lanjut. Saya bertanya-tanya apakah ada cara untuk membuktikan ini terjadi dalam produksi dari sisi SQL Server?
@ srutzky- Terima kasih. Saya akan memeriksa konfigurasi weblogik besok dan memperbarui. Namun saya berpikir tentang 37 koneksi belaka - jika SQLQueryStress melakukan 12 utas pada 10.000 iterasi = 120.000 pernyataan pilih yang tidak digabungkan, bukankah itu berarti setiap pilih membuat koneksi yang berbeda ke instance sql?
@ srutzky- Weblogics dikonfigurasikan ke koneksi pool, jadi seharusnya berfungsi dengan baik. Kumpulan koneksi dikonfigurasikan seperti ini, di masing-masing dari 4 weblog yang seimbang:
- Kapasitas awal: 10
- Kapasitas Maksimal: 50
- Kapasitas Minimum: 5
Ketika saya meningkatkan jumlah utas yang menjalankan kueri pemilihan dari tabel kosong, jumlah koneksi mencapai sekitar 47. Dengan penyatuan koneksi dinonaktifkan, saya secara konsisten melihat permintaan batch yang lebih rendah / detik (dari 10.000 turun menjadi sekitar 400). Apa yang akan terjadi setiap saat adalah bahwa 'pengecualian' pada SQLQueryStress terjadi tidak lama setelah batch / detik masuk ke palung. Ini terkait dengan konektivitas tetapi saya tidak dapat memahami mengapa ini terjadi. Ketika tidak ada tes yang berjalan, # koneksi turun menjadi sekitar 12.
Dengan koneksi pool dinonaktifkan, saya mengalami kesulitan memahami mengapa pengecualian terjadi, tapi mungkin itu seluruh pertanyaan stackExchange lainnya / pertanyaan untuk Adam Machanic?
@rutzky Saya bertanya-tanya mengapa pengecualian terjadi tanpa pooling diaktifkan, meskipun SQL Server tidak kehabisan koneksi?
SELECT COUNT(*) FROM sys.dm_exec_connections;
untuk melihat apakah nilainya sangat berbeda antara mengaktifkan penyatuan atau tidak. Berdasarkan kesalahan itu, saya pikir akan ada lebih banyak koneksi ketika pooling dinonaktifkan.
Pooling=false
atau Max Pool Size
?