SQL Server ล้างแคชแผนและสถิติการดำเนินการเป็นระยะ


24

หลังจากอัปเกรด SQL Server 2014 ถึง 2016 เซิร์ฟเวอร์จะทำการรีเซ็ตแผนการดำเนินการและdm*มุมมองแคช(เช่นdm_exec_query_stats) เป็นต้นทุก ๆ สองสามชั่วโมง

ราวกับว่ามีคนดำเนินการDBCC FREEPROCCACHEและDBCC DROPCLEANBUFFERSด้วยตนเอง (ยกเว้นไม่มีใครทำมันจะเกิดขึ้นโดยอัตโนมัติ)

ฐานข้อมูลเดียวกันทำงานได้ดีบน SQL Server 2014 และ Windows Server 2012 ทุกอย่างดำเนินไปทางใต้หลังจากย้ายไปยัง SQL Server 2016 (และ Windows Server 2016)

สิ่งที่ผมตรวจสอบ: ฐานข้อมูลไม่ได้มี "รถยนต์ใกล้ธง" เซิร์ฟเวอร์ SQL ถูกad hoc optimizedตั้งค่าเป็นtrue(ฉันคิดว่ามันจะช่วยไม่ได้) "ที่เก็บแบบสอบถาม" คือ "ปิด" เซิร์ฟเวอร์มีหน่วยความจำ 16 GB

ไม่มีประโยชน์ใน "บันทึกของเซิร์ฟเวอร์ SQL" เพียงแค่ข้อความสำรองรายสัปดาห์ ...

ฉันตรวจสอบบทความนี้ด้วยhttps://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options (เลื่อนลงไปที่ส่วน "ตัวอย่าง" และด้านบนขวา มัน) มีรายการของสถานการณ์เมื่อมีการล้างแผนโดยอัตโนมัติ ไม่มีของเหล่านั้นใช้

UPDATE:

น่าเสียดายที่ไม่มีข้อเสนอแนะใด ๆ ช่วย ให้สิทธิ์ LPIM ตรวจจับและแก้ไขคิวรีที่ไม่มีพารามิเตอร์ซึ่งสร้างแผนจำนวนมากสำหรับเคียวรีเดียวกันลด "หน่วยความจำเซิร์ฟเวอร์สูงสุด" ... ลดจำนวนแผนเรื่อย ๆ จากสองถึงสามชั่วโมงทุก 5-10 นาที หากเซิร์ฟเวอร์นั้น "ตกอยู่ภายใต้ความกดดันของหน่วยความจำ" ทำไมเวอร์ชั่น 2014 ถึงทำงานได้ดีบนเครื่องเดียวกัน

นี่คือเอาต์พุต sp_Blitz ตามที่ร้องขอ

**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...

1
ฉันแก้ไขปัญหาเดียวกันแล้วคุณสามารถลอง dba.stackexchange.com/questions/179618/query-plan-deleted/…
Yunus UYANIK

คำตอบ:


27

ขั้นแรกให้รับเวลาที่แน่นอนเมื่อล้างแคชแผน นี่เป็นวิธีที่ง่ายที่สุดในการดำเนินการ - ควรทำงานเกือบจะในทันทีและจะไม่ปิดกั้นทุกคน:

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

หากวันที่ / เวลานั้นดูแก่คุณมากกว่าที่คุณคาดไว้จะมีการล้างแคชแผนบางส่วนเท่านั้น ตัวอย่างเช่นอาจมีบางคนกำลังสร้างดัชนีใหม่หรืออัปเดตงานสถิติซึ่งจะล้างแคชแผนสำหรับวัตถุเฉพาะที่ได้รับผลกระทบ - แต่วัตถุอื่น ๆ จะยังคงติดอยู่ ฉันเห็นสิ่งนี้มากเมื่อเคียวรีระบบ (เช่นการสืบค้น DMV) ติดอยู่ แต่แผนฐานข้อมูลผู้ใช้ล้างออก

หากวันที่ / เวลานั้นอัพเดทตามช่วงเวลาที่กำหนดเช่นถ้าดูเหมือนว่าจะอัพเดททุก 2 ชั่วโมงให้พูดว่า 6:00, 8:00, 10:00, เป็นต้นจากนั้นบางคนอาจทำงานหรือแบบสอบถามที่ทำให้แคชแผน ล้างออก เมื่อคุณทราบความถี่ที่แน่นอนแล้วคุณสามารถ:

  • ดูตารางงานของคุณเพื่อดูว่ามีอะไรทำงานในช่วงเวลานั้น
  • เรียกใช้การติดตาม Profiler หรือ Extended Events trace ในช่วงเวลานั้นเพื่อค้นหาความลึกลับ (โดยปกติฉันไม่ได้เป็นแฟนตัวยงของการติดตามการผลิต แต่ถ้าคุณรู้แน่ชัดว่านักฆ่าจะนัดหยุดงานเมื่อใด - ตัวอย่างส่วนหัวของสิ่งที่กำลังทำงาน)
  • เข้าสู่sp_WhoIsActiveตารางในช่วงเวลานั้น (วิธีที่ง่ายที่สุด แต่มีโอกาสน้อยที่สุดที่จะทำให้แคบลงไปยังคิวรีที่แน่นอนที่ทำให้เกิด)

หากวันที่ / เวลานั้นเปลี่ยนไปทุกครั้งที่คุณเรียกใช้คิวรีเซิร์ฟเวอร์ของคุณอาจอยู่ภายใต้แรงกดดันของหน่วยความจำ เรียกใช้สิ่งนี้เพื่อสร้างข้อมูลการตรวจสุขภาพขั้นพื้นฐานจากนั้นคุณสามารถคัดลอก / วางลงในคำถามสแต็กของคุณเพื่อให้เราสามารถวิเคราะห์ได้:

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

(การเปิดเผย: ฉันเป็นหนึ่งในผู้เขียนsp_Blitz)

อัปเดต 2017/08/25 พร้อมกับข้อมูล sp_Blitz ของคุณ - ขอบคุณสำหรับการเรียกใช้ sp_Blitz และเพิ่มลงในคำถามของคุณและช่วยแสดงสิ่งต่างๆ คุณกำลังเรียกใช้ SQL Server 2016 Enterprise Edition บน VM ที่มี 2 คอร์และ RAM ขนาด 16GB ขั้นแรกให้ทราบอย่างรวดเร็วเกี่ยวกับการออกใบอนุญาต: หากคุณเป็นผู้ออกใบอนุญาตโดยแขกข้อกำหนดการสั่งซื้อขั้นต่ำคือ 4 คอร์ไม่ใช่ 2 (ดูคู่มือการอนุญาตให้ใช้งานเซิร์ฟเวอร์ SQLสำหรับรายละเอียดเพิ่มเติม) 4 คอร์ของ Enterprise Edition ประมาณ $ 28K USD และมันค่อนข้างแปลกที่จะเห็นว่ามีการใช้เงินจำนวนมากกับ RAM เพียง 16GB หากคุณให้สิทธิ์ใช้งาน SQL Server Enterprise Edition ในระดับโฮสต์คุณสามารถเพิกเฉยได้และเรียกใช้ VM ที่มีขนาดเล็กลง

ดูเหมือนว่า SQL Server ของคุณจะมาภายใต้แรงกดดันหน่วยความจำภายนอก คุณมี RAM 16GB และคุณตั้งค่าหน่วยความจำเซิร์ฟเวอร์สูงสุดที่ 15GB น่าเสียดายที่ 1GB นั้นยังไม่เพียงพอสำหรับระบบปฏิบัติการ (รวมถึงสิ่งอื่น ๆ ที่คุณจะใช้งานเช่นซอฟต์แวร์สำรองข้อมูลและ SSMS) ในคู่มือการตั้งค่าเซิร์ฟเวอร์ SQL ของเราเราแนะนำให้ทิ้ง 4GB หรือ 10% ฟรีแล้วแต่จำนวนใด ยิ่งใหญ่กว่า - ในกรณีของคุณนั่นคือ 4GB ดังนั้นการตั้งค่าหน่วยความจำเซิร์ฟเวอร์สูงสุดของคุณควรเป็น 12GB มากกว่า 15GB

มีหลักฐานมากขึ้นที่แสดงในการจัดสรรหน่วยความจำปัจจุบันของคุณ: คุณได้เปิดหน้าล็อคในหน่วยความจำ (LPIM) แต่คุณมีหน้าที่ล็อกในหน่วยความจำ 12.02GB เท่านั้น โอกาสนั้น (แต่ไม่รับประกัน) หมายความว่าแอปพลิเคชันอื่นจำเป็นต้องใช้หน่วยความจำดังนั้น Windows จึงส่งการแจ้งเตือนเกี่ยวกับความจำหน่วยความจำและ SQL Server มอบหน่วยความจำ 3GB อีกอันเพื่อให้แอปอื่นทำสิ่งนั้น นั่นเป็นข้อพิสูจน์เพิ่มเติมว่าคุณไม่สามารถใช้งานได้สูงสุด 15GB - คุณต้องการหน่วยความจำสำหรับสิ่งอื่น ๆ

เมื่อ SQL Server ของคุณอยู่ภายใต้แรงกดดันหน่วยความจำภายนอกและต้องการเพิ่มหน่วยความจำสำหรับแอปอื่นแคชแผนของคุณจะประสบ

ดังนั้นคุณมีตัวเลือกน้อย:

  • ตั้งค่าหน่วยความจำสูงสุดอย่างเหมาะสม - พูดขนาด 12GB (หรือต่ำกว่านั้นถ้าคุณจะเรียกใช้แอพอื่น ๆ บนเซิร์ฟเวอร์) ด้วยวิธีนี้ SQL Server จะไม่ต้องขายไฟในหน่วยความจำและล้างข้อมูลออกเพราะบางอย่าง แอปต้องการ RAM 2-3GB - จะพร้อมใช้งานแล้ว
  • หยุดการเรียกใช้แอปอื่น ๆ บนเซิร์ฟเวอร์ - ซึ่งอาจเป็นเรื่องยากหากเป็น sysadmins ตัวอื่น ๆ จากระยะไกลที่โต๊ะทำงานและทำงานอย่าง SSMS ฉันได้ตั้งค่าตัวนับสัญญาณเตือน Perfmon สำหรับจำนวนเซสชัน RDP ที่เปิดอยู่และได้รับการแจ้งเตือนเมื่อไม่มีสิ่งใดนอกเหนือจาก 0 - นั่นสามารถช่วยให้ผู้ร้ายดำเนินการได้
  • เพิ่มหน่วยความจำเพิ่มเติมให้กับ VM - แต่ฉันไม่คิดว่าคุณต้องการมันจริงๆ หลักฐานบางอย่างแสดงโดยรายงาน sp_Blitz ของ "ไม่พบการรอที่สำคัญ" ฉันไม่คิดว่าคุณอยู่ภายใต้ความกดดันของหน่วยความจำบ่อย ๆ โดยเฉพาะอย่างยิ่งเมื่อคุณรายงานว่ามันเกิดขึ้นทุก ๆ คราวแล้ว นี่คือตัวเลือกที่คุ้มค่าที่สุด

5

ตกลง OP ที่นี่ในที่สุดฉันก็แก้ไขปัญหานี้ได้โดยการอัปเดต SQL Server 2016 เป็นเวอร์ชันล่าสุด ผมมีและเมื่อวานผมติดตั้งSP1Cumulative Update 6

ฉันยังตั้ง "หน่วยความจำสูงสุด" อย่างเหมาะสมเช่นเดียวกับคำตอบของ Brent คำตอบที่ยอดเยี่ยมโดยวิธีฉันขอให้ทุกคน upvote มัน

ผ่านไปแล้ว 36 ชั่วโมงและไม่ได้มีการนับการวางแผน

เบรนต์โอซาร์ยังมีเว็บไซต์ที่ดีมากที่นี่: https://sqlserverupdates.com/เพื่อช่วยพิจารณาว่าคุณต้องการอัปเดตใดบ้าง

อีกสิ่งหนึ่งที่ช่วยตรวจจับและแก้ไขปัญหา "คีย์ต่างประเทศที่ไม่น่าเชื่อถือ" เบรนต์มีบทความที่ดีมาก (ฮ่า ๆ ๆ ใช่เบรนต์อีกครั้งฉันรู้ถูก) เกี่ยวกับวิธีการแก้ไขมันแค่ google เขาเป็นผลอันดับ # 1


1

ฉันมีปัญหานี้ในกล่องทดสอบที่บ้านของฉันและฉันพบว่าการเพิ่มสิทธิ์ 'ล็อกหน้าในหน่วยความจำ' ในบัญชีบริการ SQL Server แก้ไขปัญหา แต่ฉันไม่แน่ใจว่านี่เป็นคำแนะนำที่ดีที่สุด

ดูการเปิดใช้งานหน้าล็อคในตัวเลือกหน่วยความจำ (Windows)


หน้าล็อคในหน่วยความจำจะไม่แก้ไขหากมีการลบแคชแผนเท่านั้น (ไม่ใช่พูลบัฟเฟอร์)
เบรนต์โอซาร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.