การรวบรวม SQL ส่งผลกระทบต่อประสิทธิภาพการทำงานของ SQL Server อย่างไร


20

ฉันสร้างอินสแตนซ์ของ SQL Server 2005 และฉันผ่านการSQLServer:SQL Statistics - SQL Compilations/secวัดของ PerfMon ฉันเห็นว่าค่าเฉลี่ยประมาณ 170 หรือมากกว่านั้น

ฉันเปิดตัว SQL Profiler และค้นหา SP: Compile หรือ SQL: Compile events เห็นได้ชัดว่าพวกเขาไม่อยู่ ฉันค้นหาStored Procedure/SP:RecompileและTSQL/SQL:StmtRecompileจัดกิจกรรม จำนวนข้อมูลที่ฉันเห็นใน Profiler แสดงให้เห็นว่าสิ่งเหล่านี้เป็นเหตุการณ์ที่ไม่ถูกต้องที่ต้องดูแม้ว่าฉันจะไม่แน่ใจ

ดังนั้นคำถามของฉัน คำตอบสำหรับสิ่งเหล่านี้จะดีมาก

  1. ฉันจะดูสิ่งที่รวบรวมใน SQL Server ได้อย่างไร
  2. ฉันเลือกการวัดที่ไม่ถูกต้องเพื่อดูหรือไม่ ทั้งใน Perfmon หรือ SQL Profiler?
  3. ด้วยความเคารพStored Procedure/SP:RecompileและTSQL/SQL:StmtRecompileเหตุการณ์ใน SQL Profiler ... พวกเขาไม่ได้รวมตัวชี้วัดระยะเวลา ฉันจะวัดผลกระทบของเหตุการณ์เหล่านี้ต่อระบบได้อย่างไรหากไม่มีวิธีการดูผลกระทบต่อจังหวะเวลาต่อระบบ

คำตอบ:


33

SQL Compilations / วินาทีเป็นตัวชี้วัดที่ดี แต่เมื่อควบคู่ไปกับการจอง Batch / วินาที การรวบรวมต่อวินาทีไม่ได้บอกอะไรคุณมากนัก

คุณจะเห็น 170 ถ้าแบตช์ req ต่อวินาทีเป็นเพียง 200 (เล็กน้อยเกินจริงสำหรับผล) แล้วใช่คุณจะต้องลงไปที่ด้านล่างของสาเหตุ แต่ถ้าแบตช์ของคุณต้องใช้เวลาประมาณ 5,000 ต่อวินาทีการรวบรวม 170 ครั้งต่อวินาทีนั้นไม่เลวเลย มันเป็นกฎทั่วไปของหัวแม่มือที่Compilations / วินาทีควรจะอยู่ที่ 10% หรือน้อยกว่ารวมจอง Batch / วินาที

หากคุณต้องการเจาะลึกลงไปในสิ่งที่ถูกแคชให้รันเคียวรีต่อไปนี้ที่ใช้ DMV ที่เหมาะสม:

select
    db_name(st.dbid) as database_name,
    cp.bucketid,
    cp.usecounts,
    cp.size_in_bytes,
    cp.objtype,
    st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st

วิธีรับแผนแบบใช้ครั้งเดียวทั้งหมด (จำนวน):

;with PlanCacheCte as 
(
    select
        db_name(st.dbid) as database_name,
        cp.bucketid,
        cp.usecounts,
        cp.size_in_bytes,
        cp.objtype,
        st.text
    from sys.dm_exec_cached_plans cp
    cross apply sys.dm_exec_sql_text(cp.plan_handle) st
)
select count(*)
from PlanCacheCte
where usecounts = 1

ในการรับอัตราส่วนจำนวนแผนนับครั้งเดียวที่คุณได้เปรียบเทียบกับแผนแคชทั้งหมด:

declare @single_use_counts int, @multi_use_counts int

;with PlanCacheCte as 
(
    select
        db_name(st.dbid) as database_name,
        cp.bucketid,
        cp.usecounts,
        cp.size_in_bytes,
        cp.objtype,
        st.text
    from sys.dm_exec_cached_plans cp
    cross apply sys.dm_exec_sql_text(cp.plan_handle) st
    where cp.cacheobjtype = 'Compiled Plan'
)
select @single_use_counts = count(*)
from PlanCacheCte
where usecounts = 1

;with PlanCacheCte as 
(
    select
        db_name(st.dbid) as database_name,
        cp.bucketid,
        cp.usecounts,
        cp.size_in_bytes,
        cp.objtype,
        st.text
    from sys.dm_exec_cached_plans cp
    cross apply sys.dm_exec_sql_text(cp.plan_handle) st
    where cp.cacheobjtype = 'Compiled Plan'
)
select @multi_use_counts = count(*)
from PlanCacheCte
where usecounts > 1

select
    @single_use_counts as single_use_counts,
    @multi_use_counts as multi_use_counts,
    @single_use_counts * 1.0 / (@single_use_counts + @multi_use_counts) * 100
        as percent_single_use_counts

สำหรับช่วงเวลาที่จับภาพผ่านการติดตามเซิร์ฟเวอร์ SQL จะไม่สามารถใช้ได้สำหรับเหตุการณ์การคอมไพล์ใหม่ การเห็นระยะเวลาหรือความเจ็บปวดนั้นไม่สำคัญนักเมื่อมีการรวบรวมแผนเนื่องจากคุณไม่สามารถทำอะไรได้มากนักสำหรับสถานการณ์เป็นกรณี ๆ ไป การแก้ปัญหาคือพยายาม จำกัด การรวบรวมและการคอมไพล์ใหม่ผ่านการใช้งานซ้ำตามแผน (แบบสอบถามแบบใช้พารามิเตอร์, ขั้นตอนการจัดเก็บและอื่น ๆ )


9

มีตัวนับที่เกี่ยวข้องสามตัวที่ควรบันทึกโดยใช้ PerfMon (หรือโซลูชันบุคคลที่สาม) จุดสำคัญคือการบันทึกสถิติเหล่านี้อย่างใด

  • SQL Statistics \ Batch Request / วินาที
  • SQL Statistics \ SQL Compilations / วินาที
  • SQL Statistics \ SQL การคอมไพล์ใหม่ / วินาที

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

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

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

SELECT TOP 50
    qs.plan_generation_num,
    qs.execution_count,
    qs.statement_start_offset,
    qs.statement_end_offset,
    st.text
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
    WHERE qs.plan_generation_num > 1
    ORDER BY qs.plan_generation_num DESC

หากคุณบันทึกสถิติการใช้งาน CPU สถิติทั้งหมดสามารถเชื่อมโยงเข้าด้วยกันเพื่อค้นหาว่ามันเจ็บแค่ไหนและการแก้ไขของคุณจะช่วยได้มากแค่ไหน ในทางปฏิบัติฉันพบว่าแม้เพียงแค่แผนกลยุทธ์แบบสอบถามที่ไม่ดีเพียงอย่างเดียวบนแกนหลักในแกนกลางสามารถนำเซิร์ฟเวอร์มาที่หัวเข่า เห็นได้ชัดว่า YMMV

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