Tidak pernah mengakhiri pencarian Toko Kueri


10

Saya akan mengatakan dari awal bahwa pertanyaan saya / masalah terlihat mirip dengan yang sebelumnya ini , tetapi karena saya tidak yakin apakah penyebab atau info awal adalah sama, saya memutuskan untuk mengirim pertanyaan saya dengan lebih jelas.

Masalah yang dihadapi:

  • pada jam yang aneh (menjelang akhir hari kerja) sebuah instance produksi mulai berperilaku tidak menentu:
    • CPU tinggi untuk contoh (dari baseline ~ 30% itu menjadi sekitar dua kali lipat dan masih tumbuh)
    • peningkatan jumlah transaksi / detik (meskipun aplikasi memuat tidak melihat adanya perubahan)
    • peningkatan jumlah sesi siaga
    • peristiwa pemblokiran aneh antara sesi yang tidak pernah menampilkan perilaku ini (bahkan membaca sesi tanpa komitmen menyebabkan pemblokiran)
    • menunggu top untuk interval adalah non latch halaman di tempat 1, dengan kunci mengambil tempat 2

Investigasi awal:

  • menggunakan sp_whoIsActive kami melihat bahwa permintaan yang dijalankan oleh alat pemantauan kami memutuskan untuk berjalan sangat lambat dan mengambil banyak CPU, sesuatu yang tidak terjadi sebelumnya;
  • tingkat isolasi dibaca tidak terikat;
  • kami melihat paket yang kami lihat angka aneh: StatementEstRows = "3,86846e + 010" dengan sekitar 150 TB data yang diperkirakan akan dikembalikan
  • kami menduga fitur monitor permintaan dari alat pemantauan adalah penyebabnya, jadi kami menonaktifkan fitur tersebut (kami juga membuka tiket dengan penyedia kami untuk memeriksa apakah mereka mengetahui ada masalah)
  • dari peristiwa pertama itu, terjadi beberapa kali lagi, dengan setiap kali kita membunuh sesi, semuanya kembali normal;
  • kami menyadari bahwa kueri sangat mirip dengan salah satu kueri yang digunakan oleh MS di BOL untuk pemantauan Toko Kueri - Kueri yang baru-baru ini mengalami penurunan kinerja (membandingkan berbagai titik waktu)
  • kami menjalankan kueri yang sama secara manual dan melihat perilaku yang sama (CPU yang digunakan semakin meningkat, meningkatkan latch menunggu, kunci tak terduga .. dll)

Permintaan bersalah:

Select qt.query_sql_text, 
    q.query_id, 
    qt.query_text_id, 
    rs1.runtime_stats_id AS runtime_stats_id_1,
    interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time), 
    p1.plan_id AS plan_1, 
    rs1.avg_duration AS avg_duration_1, 
    rs2.avg_duration AS avg_duration_2,
    p2.plan_id AS plan_2, 
    interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time), 
    rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt 
Inner Join sys.query_store_query AS q 
    ON qt.query_text_id = q.query_text_id 
Inner Join sys.query_store_plan AS p1 
    ON q.query_id = p1.query_id 
Inner Join sys.query_store_runtime_stats AS rs1 
    ON p1.plan_id = rs1.plan_id 
Inner Join sys.query_store_runtime_stats_interval AS rsi1 
    ON rsi1.runtime_stats_interval_id = rs1.runtime_stats_interval_id 
 Inner Join sys.query_store_plan AS p2 
    ON q.query_id = p2.query_id 
Inner Join sys.query_store_runtime_stats AS rs2 
    ON p2.plan_id = rs2.plan_id 
Inner Join sys.query_store_runtime_stats_interval AS rsi2 
    ON rsi2.runtime_stats_interval_id = rs2.runtime_stats_interval_id
Where rsi1.start_time > DATEADD(hour, -48, GETUTCDATE()) 
    AND rsi2.start_time > rsi1.start_time 
    AND p1.plan_id <> p2.plan_id
    AND rs2.avg_duration > rs1.avg_duration * 2
Order By q.query_id, rsi1.start_time, rsi2.start_time

Pengaturan dan info:

  • SQL Server 2016 SP1 CU4 Enterprise pada kluster Windows Server 2012R2
  • Query Store diaktifkan dan dikonfigurasi sebagai default (tidak ada pengaturan berubah)
  • database yang diimpor dari contoh SQL 2005 (dan masih pada tingkat kompatibilitas 100)

Pengamatan empiris:

  • karena statistik yang sangat aneh, kami mengambil semua * plan_persist ** objek yang digunakan dalam rencana taksiran buruk (belum ada rencana sebenarnya, menyebabkan kueri tidak pernah selesai) dan memeriksa statistik, beberapa indeks yang digunakan dalam rencana tidak memiliki statistik (DBCC SHOWSTATISTICS tidak mengembalikan apa pun, pilih dari sys.stats menunjukkan fungsi NULL stats_date () untuk beberapa indeks

Solusi cepat dan kotor:

  • secara manual membuat statistik yang hilang pada objek sistem yang terkait dengan Query Store atau
  • memaksa kueri untuk berjalan menggunakan CE (traceflag) baru - yang juga akan membuat / memperbarui statistik yang diperlukan atau
  • ubah tingkat kompatibilitas basis data menjadi 130 (sehingga secara default akan menggunakan CE baru)

Jadi, pertanyaan saya yang sebenarnya adalah:

Mengapa kueri di Query Store menyebabkan masalah kinerja di seluruh instance? Apakah kita berada di wilayah bug dengan Query Store?

PS: Saya akan mengunggah beberapa file (layar cetak, statistik IO, dan paket) dalam waktu singkat.

File ditambahkan di Dropbox .

Rencana 1 - rencana perkiraan awal yang aneh dalam produksi

Rencana 2 - rencana aktual, CE lama, dalam pengujian env (perilaku yang sama, statistik aneh yang sama)

Rencana 3 - rencana aktual, CE baru, dalam pengujian env


1
Kami akhirnya menonaktifkan penyimpanan kueri, kami yakin apa penyebab dasarnya (kami memiliki lebih dari 1 masalah pasti). Pada akhirnya, CPU akan meningkatkan segala yang kami klik untuk menampilkan statistik dari toko permintaan.
A_V

Jawaban:


6

Seperti yang saya katakan dalam jawaban, tes empiris menunjukkan bahwa ada indeks pada objek sistem sys.plan_persisted * tanpa (tidak ada) statistik yang dibuat atas mereka. Saya menduga itu karena database dimigrasikan dari contoh SQL 2005, dan disimpan untuk sementara waktu pada tingkat kompatibilitas 100, sehingga CE baru tidak bisa digunakan.

Pemeriksaan jumlah baris:

Select count(1) from NoNameDB.sys.plan_persist_runtime_stats with (nolock) --60362   
Select count(1) from NoNameDB.sys.plan_persist_plan with (nolock) --1853    
Select count(1) from NoNameDB.sys.plan_persist_runtime_stats_interval with (nolock) --671    
Select count(1) from NoNameDB.sys.plan_persist_query with (nolock) --1091    
Select count(1) from NoNameDB.sys.plan_persist_query_text with (nolock) --911

Ini menunjukkan bahwa perkiraan awal salah. Selesai dengan koneksi DAC, jika tidak, tabel tidak tersedia untuk kueri.

Statistik memeriksa:

DBCC SHOW_STATISTICS ('sys.plan_persist_runtime_stats_interval', plan_persist_runtime_stats_interval_cidx);    
DBCC SHOW_STATISTICS ('sys.plan_persist_runtime_stats', plan_persist_runtime_stats_idx1);    
DBCC SHOW_STATISTICS ('sys.plan_persist_runtime_stats', plan_persist_runtime_stats_cidx);    
DBCC SHOW_STATISTICS ('sys.plan_persist_plan', plan_persist_plan_cidx);    
DBCC SHOW_STATISTICS ('sys.plan_persist_plan', plan_persist_plan_idx1);    
DBCC SHOW_STATISTICS ('sys.plan_persist_query', plan_persist_query_cidx)    
DBCC SHOW_STATISTICS ('sys.plan_persist_query_text', plan_persist_query_text_cidx);

Ini menunjukkan bahwa beberapa indeks memiliki statistik kosong (hilang, tidak ada, nol).

Perbaikan awal:

UPDATE STATISTICS sys.plan_persist_runtime_stats WITH fullscan;
UPDATE STATISTICS sys.plan_persist_plan WITH fullscan;
UPDATE STATISTICS sys.plan_persist_runtime_stats_interval WITH fullscan;
UPDATE STATISTICS sys.plan_persist_query WITH fullscan;
UPDATE STATISTICS sys.plan_persist_query_text WITH fullscan;

Jenis ini memperbaiki statistik dan membuat kueri selesai dalam 10-12 detik.

Perbaikan kedua :

(diverifikasi hanya pada lingkungan pengujian) dan kemungkinan besar yang tepat, karena menunjukkan statistik terbaik untuk kueri, adalah mengubah tingkat kompatibilitas database menjadi 130. Hasil akhirnya adalah bahwa kueri berakhir sekitar 10-12 detik dengan statistik angka normal (baris 10rb).

Perbaikan tingkat menengah :

DBCC TRACEON (2312) -- new CE

Beberapa bantuan terkait tentang statistik pada tabel tersembunyi sistem.


3

Masalah mendasar, yang terlihat jika Anda membuka rencana aktual dalam SSMS dan melihat penggunaan CPU (atau memeriksa XML), adalah node 32, sebuah TVF. Pelakunya dalam permintaan Query Store lambat adalah akses berulang TVF dalam memori .

Biaya TVF

Tidak peduli berapa banyak baris yang dikembalikan dari TVF ini, hanya berapa kali mereka diakses. Cara mengatasinya adalah apa pun yang dapat Anda lakukan untuk mendorong rencana Anda agar tidak membacanya berulang kali.

Berdasarkan pada debugging terbatas saya (baik dalam keterampilan dan waktu yang dihabiskan), hipotesis saya adalah bahwa keseluruhan memori yang ditetapkan untuk komponen dalam-memori tertentu dari data Query Store dipindai dengan setiap eksekusi TVF. Saya belum dapat memengaruhi alokasi memori ini dengan sp_query_store_flush_dbatau DBCC FREESYSTEMCACHE.

Solusi yang berhasil sejauh ini termasuk panduan rencana, mengisyaratkan ( OPTION(HASH JOIN, LOOP JOIN)telah bekerja cukup baik untuk saya sejauh ini), dan menjalankan kueri Toko Kueri pada simpul read-only dari AG.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.