ไม่สิ้นสุดการค้นหาใน Query Store


10

ฉันจะบอกตั้งแต่ต้นว่าคำถาม / ปัญหาของฉันมีลักษณะคล้ายกับนี้ก่อนหน้านี้หนึ่ง แต่เนื่องจากผมไม่แน่ใจว่าถ้าสาเหตุหรือข้อมูลเริ่มต้นเหมือนกันฉันตัดสินใจที่จะโพสต์คำถามของฉันที่มีรายละเอียดบางอย่างมากขึ้น

ปัญหาในมือ:

  • ในเวลาไม่กี่ชั่วโมง (ใกล้ถึงสิ้นวันทำการ) ตัวอย่างการผลิตจะเริ่มทำงานผิดปกติ:
    • CPU สูงสำหรับอินสแตนซ์ (จากพื้นฐานประมาณ 30% มันจะเพิ่มขึ้นเป็นสองเท่าและยังคงเติบโตอยู่)
    • เพิ่มจำนวนธุรกรรม / วินาที (แม้ว่าการโหลดแอปจะไม่เห็นการเปลี่ยนแปลงใด ๆ )
    • เพิ่มจำนวนเซสชันว่าง
    • เหตุการณ์การบล็อกแปลก ๆ ระหว่างเซสชันที่ไม่เคยแสดงพฤติกรรมนี้ (แม้จะอ่านเซสชันที่ไม่มีข้อผูกมัดก็ทำให้เกิดการบล็อก)
    • การรอช่วงบนสุดเป็นช่วงที่ไม่ใช่การสลักหน้าในอันดับที่ 1 โดยมีการล็อกตำแหน่งที่ 2

การตรวจสอบเบื้องต้น:

  • การใช้ sp_whoIsActive เราเห็นว่าการสืบค้นที่ดำเนินการโดยเครื่องมือตรวจสอบของเราตัดสินใจที่จะทำงานช้ามากและจับ CPU จำนวนมากสิ่งที่ไม่เคยเกิดขึ้นมาก่อน
  • ระดับการแยกของมันถูกอ่านปราศจากข้อผูกมัด
  • เราดูแผนที่เราเห็นตัวเลขที่แปลกประหลาด: StatementEstRows = "3.86846e + 010" โดยมีข้อมูลประมาณ 150 TB เพื่อส่งคืน
  • เราสงสัยว่าคุณลักษณะการตรวจสอบข้อความค้นหาของเครื่องมือตรวจสอบนั้นเป็นสาเหตุดังนั้นเราจึงปิดการใช้งานคุณลักษณะนี้ (เราได้เปิดตั๋วกับผู้ให้บริการของเราเพื่อตรวจสอบว่าพวกเขาตระหนักถึงปัญหาใด ๆ หรือไม่)
  • จากเหตุการณ์แรกนั้นมันเกิดขึ้นอีกสองสามครั้งทุกครั้งที่เราฆ่าเซสชันทุกอย่างกลับสู่ปกติ
  • เราทราบว่าคิวรีนั้นคล้ายกันมากกับหนึ่งในคิวรีที่ MS ใช้ใน BOL สำหรับการตรวจสอบ Query Store - แบบสอบถามที่ถดถอยเมื่อเร็ว ๆ นี้ในประสิทธิภาพ (เปรียบเทียบจุดต่าง ๆ ในเวลา)
  • เราเรียกใช้แบบสอบถามเดียวกันด้วยตนเองและดูพฤติกรรมเดียวกัน (CPU ที่เคยเพิ่มขึ้นเพิ่มการรอ latch ล็อคที่ไม่คาดคิด .. ฯลฯ )

ข้อความค้นหามีความผิด:

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

การตั้งค่าและข้อมูล:

  • SQL Server 2016 SP1 CU4 Enterprise ในคลัสเตอร์ Windows Server 2012R2
  • Query Store เปิดใช้งานและกำหนดค่าเป็นค่าเริ่มต้น (ไม่มีการเปลี่ยนแปลงการตั้งค่า)
  • ฐานข้อมูลที่นำเข้าจากอินสแตนซ์ SQL 2005 (และยังอยู่ในระดับความเข้ากันได้ 100)

การสังเกตเชิงประจักษ์:

  • เนื่องจากสถิติที่แปลกประหลาดมากเราจึงเอา * plan_persist ** วัตถุทั้งหมดที่ใช้ในแผนโดยประมาณที่ไม่ดี (ยังไม่มีแผนจริงทำให้แบบสอบถามไม่เสร็จ) และตรวจสอบสถิติดัชนีบางส่วนที่ใช้ในแผนไม่มีสถิติใด ๆ (DBCC SHOWSTATISTICS ไม่ได้ส่งคืนสิ่งใดเลือกจาก sys.stats แสดงให้เห็นว่าฟังก์ชัน NULL stats_date () สำหรับดัชนีบางส่วน

วิธีแก้ปัญหาที่รวดเร็วและสกปรก:

  • สร้างสถิติที่หายไปด้วยตนเองในวัตถุระบบที่เกี่ยวข้องกับ Query Store หรือ
  • บังคับให้แบบสอบถามรันโดยใช้ CE ใหม่ (traceflag) - ซึ่งจะสร้าง / อัปเดตสถิติที่จำเป็นหรือ
  • เปลี่ยนระดับความเข้ากันได้ของฐานข้อมูลเป็น 130 (ตามค่าเริ่มต้นจะใช้ CE ใหม่)

ดังนั้นคำถามจริงของฉันจะเป็น:

เหตุใดข้อความค้นหาใน Query Store จึงทำให้เกิดปัญหาประสิทธิภาพในอินสแตนซ์ทั้งหมด พวกเราอยู่ในเขตบั๊กกับ Query Store หรือไม่?

PS: ฉันจะอัปโหลดบางไฟล์ (หน้าจอการพิมพ์สถิติ IO และแผน) ในระยะสั้น

เพิ่มไฟล์ในDropbox

แผน 1 - แผนเริ่มต้นที่ผิดปกติในการผลิต

แผน 2 - แผนจริง, CE เก่า, ในการทดสอบ env (พฤติกรรมเดียวกัน, สถิติแปลกประหลาดเดียวกัน)

แผน 3 - แผนจริง, CE ใหม่, ในการทดสอบ env


1
เราปิดการใช้งานที่เก็บแบบสอบถามเราไม่แน่ใจว่าสาเหตุของปัญหาคืออะไร (เรามีปัญหามากกว่า 1 ข้อ) ในตอนท้ายของฉัน CPU จะเพิ่มทุกอย่างที่เราคลิกเพื่อแสดงสถิติจากที่เก็บแบบสอบถาม
A_V

คำตอบ:


6

ดังที่ฉันได้กล่าวไว้ในคำตอบการทดสอบเชิงประจักษ์แสดงให้เห็นว่ามีดัชนีของวัตถุระบบ sys.plan_persisted * โดยไม่มีสถิติใด ๆ (ไม่มี) ที่สร้างขึ้นเหนือพวกเขา ฉันสงสัยว่าเป็นเพราะฐานข้อมูลถูกย้ายจากอินสแตนซ์ SQL 2005 และเก็บรักษาไว้ที่ระดับความเข้ากันได้ 100 ในขณะนั้นจึงไม่สามารถใช้ CE ใหม่ได้

การตรวจนับแถว:

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

สิ่งนี้แสดงให้เห็นว่าการประมาณการเบื้องต้นผิด เสร็จสิ้นด้วยการเชื่อมต่อ DAC มิฉะนั้นตารางจะไม่สามารถสืบค้นได้

ตรวจสอบสถิติ:

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);

สิ่งนี้แสดงให้เห็นว่าดัชนีบางตัวมีสถานะว่างเปล่า (หายไปไม่มีศูนย์)

การแก้ไขเริ่มต้น:

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;

ประเภทของสถิตินี้คงที่และทำให้การค้นหาเสร็จสิ้นใน 10-12 วินาที

การแก้ไขที่สอง :

(ตรวจสอบเฉพาะในสภาพแวดล้อมการทดสอบ) และน่าจะเป็นสิ่งที่เหมาะสมที่สุดเนื่องจากมันแสดงสถิติที่ดีที่สุดสำหรับแบบสอบถามคือการเปลี่ยนระดับความเข้ากันได้ของฐานข้อมูลเป็น 130 ผลลัพธ์สุดท้ายคือแบบสอบถามสิ้นสุดลงในประมาณ 10-12 วินาทีด้วย สถิติจำนวนปกติ (10k แถว)

การแก้ไขระดับกลาง :

DBCC TRACEON (2312) -- new CE

ความช่วยเหลือที่เกี่ยวข้องเกี่ยวกับสถิติในตารางที่ซ่อนอยู่ของระบบ


3

ปัญหาพื้นฐานซึ่งมองเห็นได้ถ้าคุณเปิดแผนจริงใน SSMS และดูที่การใช้งาน CPU (หรือตรวจสอบ XML) คือโหนด 32 ซึ่งเป็น TVF ผู้กระทำผิดในการสืบค้นร้านแบบสอบถามช้าซ้ำการเข้าถึงของ TVFs

ค่าใช้จ่าย TVF

ไม่สำคัญว่าจะถูกส่งกลับจำนวนแถวจาก TVF เหล่านี้กี่ครั้งเท่านั้นที่สามารถเข้าถึงได้ การแก้ไขจะเป็นสิ่งที่คุณสามารถทำได้เพื่อผลักดันแผนการของคุณออกไปจากการอ่านหลาย ๆ ครั้ง

จากการดีบักแบบ จำกัด ของฉัน (ทั้งในทักษะและเวลาที่ใช้) สมมติฐานของฉันคือหน่วยความจำทั้งหมดที่กำหนดสำหรับองค์ประกอบในหน่วยความจำเฉพาะของข้อมูล Query Store จะถูกสแกนด้วยการประมวลผล TVF แต่ละครั้ง ผมยังไม่ได้รับสามารถที่จะส่งผลกระทบต่อการจัดสรรหน่วยความจำนี้ด้วยหรือsp_query_store_flush_dbDBCC FREESYSTEMCACHE

การแก้ปัญหาที่ประสบความสำเร็จจนถึงตอนนี้มีคำแนะนำแผนแนะนำ ( OPTION(HASH JOIN, LOOP JOIN)ทำงานได้ดีพอสำหรับฉันจนถึงตอนนี้) และเรียกใช้แบบสอบถาม Query Store บนโหนดแบบอ่านอย่างเดียวของ AG

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