SQL Server membersihkan cache rencana dan statistik eksekusi secara berkala

24

Setelah memutakhirkan SQL Server 2014 hingga 2016, server terus mengatur ulang rencana dan dm*tampilan eksekusi yang di-cache (seperti dm_exec_query_stats) dll. Setiap beberapa jam

Seolah-olah seseorang mengeksekusi DBCC FREEPROCCACHEdan DBCC DROPCLEANBUFFERSsecara manual (kecuali tidak ada yang melakukannya, itu terjadi secara otomatis).

Basis data yang sama berfungsi dengan baik pada SQL Server 2014 dan Windows Server 2012, semuanya berjalan ke selatan setelah pindah ke SQL Server 2016 (dan Windows server 2016)

Hal-hal yang saya periksa: database tidak memiliki bendera "tutup otomatis". Server SQL ad hoc optimizeddiatur ke true(saya pikir itu akan membantu, itu tidak). "Toko permintaan" tidak aktif ". Server memiliki memori 16 GB.

Tidak ada yang membantu dalam "SQL Server log". Hanya pesan cadangan mingguan ...

Saya juga memeriksa artikel ini https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options (gulir ke bawah ke bagian "Contoh", dan tepat di atas itu) ada daftar situasi ketika rencana dihapus secara otomatis. Tidak ada yang berlaku.

MEMPERBARUI:

Sayangnya, tidak ada saran yang membantu. Memberikan izin LPIM, mendeteksi, dan memperbaiki kueri yang tidak diparameterisasi yang menghasilkan banyak paket untuk kueri yang sama, menurunkan "memori server maks" ... Paket terus diatur ulang secara acak, dari setiap beberapa jam hingga setiap 5-10 menit. Jika server "di bawah tekanan memori" kenapa versi 2014 bekerja dengan baik pada mesin yang sama.

Inilah output sp_Blitz seperti yang diminta

**Priority 10: Performance**:

- Query Store Disabled - The new SQL Server 2016 Query Store feature has not been enabled on this database.

    * xxx


**Priority 50: Server Info**:

- Instant File Initialization Not Enabled  - Consider enabling IFI for faster restores and data file growths.


**Priority 100: Performance**:

- Resource Governor Enabled  - Resource Governor is enabled.  Queries may be throttled.  Make sure you understand how the Classifier Function is configured.


**Priority 120: Query Plans**:

- Implicit Conversion Affecting Cardinality - One of the top resource-intensive queries has an implicit conversion that is affecting cardinality estimation.

    * 

- Missing Index - One of the top resource-intensive queries may be dramatically improved by adding an index.

    * 

- RID or Key Lookups - One of the top resource-intensive queries contains RID or Key Lookups. Try to avoid them by creating covering indexes.

    * 

**Priority 170: File Configuration**:

- System Database on C Drive
    * master - The master database has a file on the C drive.  Putting system databases on the C drive runs the risk of crashing the server when it runs out of space.

    * model - The model database has a file on the C drive.  Putting system databases on the C drive runs the risk of crashing the server when it runs out of space.

    * msdb - The msdb database has a file on the C drive.  Putting system databases on the C drive runs the risk of crashing the server when it runs out of space.


**Priority 200: Backup**:

- MSDB Backup History Not Purged msdb - Database backup history retained back to Jun 10 2017  9:47PM


**Priority 200: Informational**:

- Backup Compression Default Off  - Uncompressed full backups have happened recently, and backup compression is not turned on at the server level. Backup compression is included with SQL Server 2008R2 & newer, even in Standard Edition. We recommend turning backup compression on by default so that ad-hoc backups will get compressed.


**Priority 200: Non-Default Server Config**:

- Agent XPs  - This sp_configure option has been changed.  Its default value is 0 and it has been set to 1.

- max server memory (MB)  - This sp_configure option has been changed.  Its default value is 2147483647 and it has been set to 15000.

- optimize for ad hoc workloads  - This sp_configure option has been changed.  Its default value is 0 and it has been set to 1.

- show advanced options  - This sp_configure option has been changed.  Its default value is 0 and it has been set to 1.

- xp_cmdshell  - This sp_configure option has been changed.  Its default value is 0 and it has been set to 1.


**Priority 200: Performance**:

- Buffer Pool Extensions Enabled  - You have Buffer Pool Extensions enabled, and one lives here: Z:\sql_buffer_pool.BPE. It's currently 60.00000000000 GB. Did you know that BPEs only provide single threaded access 8KB (one page) at a time?

- cost threshold for parallelism  - Set to 5, its default value. Changing this sp_configure setting may reduce CXPACKET waits.

**Priority 240: Wait Stats**:

- No Significant Waits Detected  - This server might be just sitting around idle, or someone may have cleared wait stats recently.

**Priority 250: Informational**:

- SQL Server Agent is running under an NT Service account  - I'm running as NT Service\SQLSERVERAGENT. I wish I had an Active Directory service account instead.

- SQL Server is running under an NT Service account  - I'm running as NT Service\MSSQLSERVER. I wish I had an Active Directory service account instead.

**Priority 250: Server Info**:

- Default Trace Contents  - The default trace holds 125 hours of data between Aug 19 2017 11:55AM and Aug 24 2017  4:59PM. The default trace files are located in: C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Log

- Hardware  - Logical processors: 2. Physical memory: 15GB.

- Hardware - NUMA Config  - Node: 0 State: ONLINE Online schedulers: 2 Offline schedulers: 0 Processor Group: 0 Memory node: 0 Memory VAS Reserved GB: 29

- Locked Pages In Memory Enabled  - You currently have 12.02534484863 GB of pages locked in memory.

- Memory Model Unconventional  - Memory Model: LOCK_PAGES

- Server Last Restart  - Aug 20 2017 12:32PM

- Server Name  - xx

- Services
 - Service: SQL Full-text Filter Daemon Launcher (MSSQLSERVER) runs under service account NT Service\MSSQLFDLauncher. Last startup time: not shown.. Startup type: Manual, currently Running.

 - Service: SQL Server (MSSQLSERVER) runs under service account NT Service\MSSQLSERVER. Last startup time: Aug 20 2017 12:32PM. Startup type: Automatic, currently Running.

 - Service: SQL Server Agent (MSSQLSERVER) runs under service account NT Service\SQLSERVERAGENT. Last startup time: not shown.. Startup type: Automatic, currently Running.

- SQL Server Last Restart  - Aug 20 2017 12:33PM

- SQL Server Service  - Version: 13.0.4446.0. Patch Level: SP1. Edition: Enterprise Edition (64-bit). AlwaysOn Enabled: 0. AlwaysOn Mgr Status: 2

- Virtual Server  - Type: (HYPERVISOR)

- Windows Version  - You're running a pretty modern version of Windows: Server 2012R2 era, version 6.3


**Priority 254: Rundate**:

 - Captain's log: stardate something and something...
jitbit
sumber
1
Saya telah memecahkan masalah yang sama, Anda dapat mencoba. dba.stackexchange.com/questions/179618/query-plan-deleted/…
Yunus UYANIK

Jawaban:

27

Pertama, dapatkan waktu yang tepat ketika cache rencana sedang dihapus. Inilah cara termudah untuk melakukannya - itu harus dijalankan hampir secara instan, dan tidak akan memblokir siapa pun:

SELECT TOP 1 creation_time
FROM sys.dm_exec_query_stats WITH (NOLOCK)
ORDER BY creation_time;

Jika tanggal / waktu itu tampak lebih tua dari perkiraan Anda , maka hanya sebagian dari cache paket yang dihapus. Misalnya, mungkin seseorang sedang melakukan pembangunan kembali indeks atau memperbarui pekerjaan statistik, yang akan menghapus cache rencana untuk objek tertentu yang terpengaruh - tetapi objek lain masih akan tetap ada. Saya sering melihat ini ketika kueri sistem (seperti permintaan DMV) bertahan, tetapi rencana basis data pengguna dihapus.

Jika tanggal / waktu itu diperbarui pada interval tertentu , seperti jika tampaknya memperbarui tepat setiap 2 jam untuk mengatakan 6:00, 8:00, 10:00, dll, maka seseorang mungkin menjalankan pekerjaan atau permintaan yang menyebabkan cache rencana untuk mengosongkan. Setelah Anda mengetahui frekuensi pastinya, maka Anda dapat:

  • Lihatlah jadwal pekerjaan Anda untuk melihat apa yang berjalan pada interval itu
  • Jalankan jejak Profiler atau Jejak Peristiwa Diperpanjang selama rentang waktu itu untuk mengetahui misteri (Saya biasanya bukan penggemar penelusuran dalam produksi, tetapi jika Anda tahu persis kapan pembunuh akan menyerang, cukup mudah untuk menyalakan rendah - Sampel awal dari apa yang berjalan)
  • Log sp_WhoIsActiveke tabel selama waktu itu (metode termudah, tetapi paling tidak mempersempitnya ke kueri persis yang menyebabkannya)

Jika tanggal / waktu itu terus berubah setiap kali Anda menjalankan kueri , maka server Anda mungkin berada di bawah tekanan memori. Jalankan ini untuk menghasilkan info pemeriksaan kesehatan dasar, dan kemudian Anda dapat menyalin / menempelkannya ke pertanyaan Stack Anda sehingga kami dapat mendiagnosisnya:

sp_Blitz @OutputType = 'markdown', @CheckServerInfo = 1, @CheckUserDatabaseObjects = 1

(Pengungkapan: Saya salah satu penulis sp_Blitz.)

Diperbarui 2017/08/25 dengan data sp_Blitz Anda - terima kasih telah menjalankan sp_Blitz dan menambahkannya ke pertanyaan Anda, dan itu benar-benar membantu menunjukkan beberapa hal. Anda menjalankan SQL Server 2016 Enterprise Edition pada VM dengan 2 core dan 16GB RAM. Pertama, catatan singkat tentang lisensi: jika Anda dilisensikan oleh tamu, persyaratan pembelian minimum adalah 4 core, bukan 2. (Lihat Panduan Perizinan SQL Server untuk lebih jelasnya.) 4 core Edisi Enterprise adalah sekitar $ 28K USD , dan itu sangat tidak biasa untuk melihat bahwa banyak uang lisensi dihabiskan hanya pada 16GB RAM. Jika Anda melisensikan SQL Server Enterprise Edition di tingkat host, Anda dapat mengabaikannya dan menjalankan VM yang lebih kecil.

Sepertinya SQL Server Anda berada di bawah tekanan memori eksternal. Anda memiliki RAM 16GB, dan Anda telah menetapkan memori server maks pada 15GB. Sayangnya, 1GB tidak cukup tersisa untuk sistem operasi (plus apa pun yang akan Anda jalankan di sana, seperti perangkat lunak cadangan dan SSMS.) Dalam Panduan Penyiapan SQL Server kami, kami sarankan untuk membiarkan 4GB atau 10% gratis, mana saja lebih besar - dalam kasus Anda, itu akan menjadi 4GB, jadi pengaturan memori server maks Anda harus 12GB daripada 15GB.

Lebih banyak bukti muncul di alokasi memori Anda saat ini: Anda telah mengunci halaman di memori (LPIM) dihidupkan, tetapi Anda hanya punya 12.02GB halaman terkunci di memori. Kemungkinan itu (tetapi tidak dijamin) berarti bahwa beberapa aplikasi lain membutuhkan memori, jadi Windows mengirimkan pemberitahuan tekanan memori, dan SQL Server menyerahkan 3GB memori lainnya untuk membiarkan aplikasi lain melakukan hal tersebut. Itu lebih banyak bukti bahwa Anda tidak dapat benar-benar menggunakan maks 15GB - Anda perlu memori untuk hal-hal lain.

Ketika SQL Server Anda berada di bawah tekanan memori eksternal dan perlu membebaskan memori untuk aplikasi lain, cache rencana Anda akan menderita.

Jadi, Anda punya beberapa opsi:

  • Tetapkan memori maks dengan tepat - katakanlah, 12GB (atau bahkan lebih rendah jika Anda akan menjalankan aplikasi lain di server.) Dengan begitu, SQL Server tidak harus memiliki penjualan api di memori dan membuang barang hanya karena beberapa lainnya aplikasi membutuhkan 2-3GB RAM - sudah tersedia
  • Hentikan menjalankan aplikasi lain di server - ini bisa jadi sulit jika itu adalah sysadmin remote lainnya yang menjalankan dan menjalankan hal-hal seperti SSMS. Saya telah menyiapkan alarm penghitung Perfmon untuk jumlah sesi RDP yang terbuka, dan memberi tahu bila ada yang lain dari 0 - yang dapat membantu menangkap pelakunya dalam aksi.
  • Tambahkan lebih banyak memori ke VM - tetapi saya tidak berpikir Anda benar-benar membutuhkannya. Beberapa bukti ditunjukkan oleh laporan sp_Blitz dari "tidak ada menunggu signifikan terdeteksi." Saya tidak berpikir Anda sering mengalami tekanan memori, terutama karena Anda melaporkan bahwa itu hanya terjadi sesekali. Ini adalah pilihan yang paling hemat biaya.
Brent Ozar
sumber
5

Oke, OP di sini, saya akhirnya memperbaiki masalah ini dengan memperbarui SQL Server 2016 ke versi terbaru. Saya telah SP1dan kemarin saya instal Cumulative Update 6.

Saya juga mengatur "memori maks" dengan tepat seperti yang disarankan jawaban Brent. Ngomong-ngomong, jawaban yang bagus, saya mendorong semua orang untuk membenarkannya.

Sudah 36 jam dan terus bertambah, rencana tidak diatur ulang.

Brent Ozar juga memiliki situs web yang sangat bagus di sini: https://sqlserverupdates.com/ untuk membantu menentukan pembaruan mana yang Anda butuhkan.

Satu hal lain yang membantu adalah mendeteksi dan menyelesaikan masalah "kunci asing yang tidak dipercaya". Brent memiliki artikel yang sangat bagus (hahah, ya, Brent lagi, saya tahu benar) tentang cara mengatasinya, hanya google, dia hasil # 1

jitbit
sumber
1

Saya telah memiliki masalah ini di kotak pengujian rumah saya dan saya menemukan bahwa dengan menambahkan izin 'Kunci Halaman dalam memori' ke akun layanan SQL Server memecahkan masalah, tetapi saya tidak yakin ini adalah saran terbaik.

Lihat Mengaktifkan Halaman Kunci di Opsi Memori (Windows)

MrKudz
sumber
Kunci halaman dalam memori tidak akan memperbaikinya jika hanya cache rencana yang dihapus (bukan kumpulan buffer).
Brent Ozar