มีวิธีการตรวจสอบว่าแบบสอบถาม SQL Server ทำงานในหน่วยความจำหรือไปที่ดิสก์?


13

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

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

การประมวลผลแต่ละแถวเมื่อนำเข้าข้อมูลใช้เวลา 300ms ต่อแถวดังนั้นการนำเข้าขนาดเล็กจึงใช้เวลาประมวลผลหลายนาที

อย่างไรก็ตามตารางที่เกี่ยวข้องกับกระบวนการส่วนใหญ่ค่อนข้างเล็ก ฉันคิดว่าถ้าตารางเหล่านี้ทั้งหมดอยู่ในความทรงจำอย่างเต็มที่บางทีอาจมีไม่มากนักที่จะได้รับจากการเขียนสิ่งนี้

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

ดังนั้นคำถามคือ:
- มีวิธีการกำหนดตารางใดตรึงในหน่วยความจำทั้งหมดหรือไม่
- มีวิธีเปิดใช้การติดตามเพื่อตรวจสอบขั้นตอนการจัดเก็บซ้อนเพื่อค้นหาส่วนที่มีราคาแพงโดยเฉพาะหรือไม่

หมายเหตุ: สิ่งนี้อยู่ใน SQL Server 2008 R2

คำตอบ:


12

คุณสามารถใช้หนึ่งในสองแบบสอบถามนี้เพื่อดูการอ่านตรรกะทั้งหมดและการอ่านทางกายภาพทั้งหมด

SELECT  DB_NAME(st.dbid) Db,
        OBJECT_NAME(st.objectid, st.dbid) Prc,
        qs.execution_count,
        qs.total_logical_reads,
        qs.total_physical_reads,
        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;

SELECT  DB_NAME(database_id) Db,
        OBJECT_NAME(object_id, database_id) Prc,
        execution_count,
        total_logical_reads,
        total_physical_reads
FROM    sys.dm_exec_procedure_stats ps;

คนแรกแบ่งคำสั่งนี้ลงโดยคนที่สองนับในขั้นตอนทั้งหมด

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

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

มีคอลัมน์เพิ่มเติมจำนวนมากใน DMVs ด้านบนที่คุณอาจพบว่าน่าสนใจเช่นกัน


ดัชนีช่วยลดการอ่านเชิงตรรกะได้อย่างไร

ใน SQL Server ข้อมูลทั้งหมดจะถูกจัดระเบียบในบล็อกขนาด 8KB บล็อกเหล่านี้เรียกว่า "หน้า"

ทุกตารางมีหน้า "เมตา" ที่มีข้อมูลเกี่ยวกับโครงสร้างของตารางเช่นเดียวกับหน้าพาต้า หากไม่มีดัชนีอยู่และคุณเรียกใช้SELECT * FROM tbl WHERE Id = 7คิวรีเช่นSQL Server ต้องค้นหาแถวนี้หรือแถวเหล่านี้ในตารางทั้งหมด ดังนั้นจะอ่านทีละหน้าวนรอบทุกแถวในแต่ละหน้าเพื่อกำหนดแถวที่เหมาะสมกับWHEREอนุประโยค ดังนั้นหากตารางต้องการเก็บ 1,000,000 หน้าแบบสอบถามนี้จะใช้เวลา 1,000,000 อ่านตรรกะในการดำเนินการ

หากคุณมีดัชนี SQL Server จะเรียงลำดับข้อมูลตามตรรกะภายในหน้าและสร้างรายการที่เชื่อมโยงระหว่างหน้า สิ่งนี้ทำให้สามารถเรียกใช้ORDER BYคิวรีที่มีการเรียกใช้โดยไม่มีการดำเนินการเรียงลำดับราคาแพง แต่สิ่งสำคัญคือการเรียงลำดับ SQL Server จะเพิ่มB + Treeลงในตาราง ต้นไม้ B + เป็นโครงสร้างเทียบได้กับดัชนีในหนังสือซึ่งการค้นหาคำหลักที่เฉพาะเจาะจงทำให้ฉันสามารถข้ามไปยังหน้าที่มีคำหลักได้โดยตรง หนังสือทั่วไปมีเพียงระดับดัชนีเดียวในขณะที่ B + Tree สามารถมีได้หลายระดับ ลองนึกถึงหนังสือเล่มใหญ่ที่มีดัชนีตัวเองยาวหลายหน้า ในกรณีเช่นนี้การเพิ่มเลเยอร์ดัชนีเพิ่มเติมที่บอกเราในหน้าซึ่งSจะพบคำดัชนีที่ขึ้นต้นด้วย

ต้นไม้ B + ได้รับการปรับให้มีระดับน้อยที่สุดเท่าที่จะเป็นไปได้ในขณะเดียวกันก็ให้คุณสมบัติที่บันทึกใด ๆ ในดัชนีสามารถพบได้โดยการอ่านหนึ่งหน้าต่อระดับดัชนี ดังนั้นสมมติข้างต้นแบบสอบถามเมื่อคุณมีดัชนีเรียงตามWHERE Id = 7 Idสมมุติว่าดัชนีมี 5 ระดับ ตอนนี้เพื่อค้นหาระเบียนทั้งหมดที่ตรงกับแบบสอบถามนี้ฉันต้องอ่านหนึ่งหน้าต่อระดับดัชนี (นั่นคือ 5 หน้า) ซึ่งเรียกว่า "ดัชนีค้นหา" หากมีหลายระเบียนที่เหมาะสมกับการเรียกเก็บเงินฉันอาจต้องทำตามดัชนีที่เรียงไว้สักครู่เพื่อดึงข้อมูลทั้งหมดของพวกเขา แต่สมมติว่ามีเพียงหนึ่งระเบียน

ดังนั้นหากไม่มีดัชนีที่ใช้เคียวรีนั้นจำเป็นต้องอ่าน 1,000,000 ครั้งโดยที่ดัชนีนั้นต้องการการอ่าน 5 ครั้ง แม้ว่าการอ่านแบบโลจิคัลคือการดำเนินการในหน่วยความจำ แต่ก็มีค่าใช้จ่ายจำนวนมาก แต่ในความเป็นจริงแล้วมันเป็นการดำเนินการที่แพงที่สุดในการสืบค้นที่ไม่สำคัญเหมือนที่กล่าวมาข้างต้น ดังนั้นการลดปริมาณการอ่านเชิงตรรกะที่จำเป็นโดยปัจจัย 200,000 จะช่วยเพิ่มความเร็วในการสืบค้นของคุณด้วยปัจจัยที่คล้ายกัน

ดังนั้นการอ่านแบบลอจิคัลจะไม่เทียบเท่ากับการสแกนแบบตาราง แต่การสแกนแบบตารางทำให้เกิดการอ่านแบบลอจิคัลมากกว่าการค้นหาดัชนี


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

1
เพิ่มคำอธิบายลงในคำตอบของฉันด้านบน
เซบาสเตียนมี

ขอบคุณ แม้สมมติว่ามีดัชนีที่เหมาะสมอยู่ในตารางทั้งหมดที่เกี่ยวข้อง ... ฉันคิดว่ายังคงมีประสิทธิภาพที่แตกต่างอย่างมากระหว่างตารางที่ถูกตรึงในหน่วยความจำกับการอ่านจากดิสก์ (สมมติว่าดัชนีเดียวกันในสถานการณ์ทั้งสอง) ... หรืออื่น ๆ คำการเพิ่มดัชนีจะช่วยให้คุณเพิ่ม% ประสิทธิภาพในการทำงานของเครื่องที่มี RAM น้อยกว่าในเครื่องที่มีหน่วยความจำน้อยลง .... ถูกต้องใช่ไหม

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

2
ไมเนอร์ nitpick - ฉันคิดว่าหน้าเว็บมีขนาด 8kb :-) คำตอบที่ดี.
onupdatecascade

3
  • มีวิธีการเปิดใช้การติดตามเพื่อตรวจสอบขั้นตอนการจัดเก็บซ้อนกันเพื่อค้นหาส่วนที่มีราคาแพงโดยเฉพาะอย่างยิ่ง?

คุณสามารถใช้ SQL Profiler เมื่อคุณเริ่มติดตามคุณควรเลือก RPC เสร็จสมบูรณ์เริ่มต้น SP, SP StmtStarting และ SP StmtCompleted (ดูภาพด้านล่าง)

ป้อนคำอธิบายรูปภาพที่นี่

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

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


1

ดูเหมือนคำถามเพิ่มประสิทธิภาพข้อความค้นหาทั่วไป จากคำอธิบายของคุณฉันจะ:

  1. ดูรหัสเพื่อดูว่าใช้การประมวลผลแบบแถวต่อแถวหรือไม่ ถ้าเป็นเช่นนั้นคำสั่งการปรับปรุงขนาดมักจะสามารถทำได้โดยใช้ตรรกะเดียวกันโดยใช้ชุด (หลายแถวประมวลผลในเวลาเดียวกัน) กล่าวอีกนัยหนึ่งถ้ามันทำตัวเหมือน "วนรอบแต่ละแถว" ให้เปลี่ยนเป็น "ประมวลผลแถวทั้งหมด" SQL เก่งในเรื่องนั้นเพราะเครื่องมือเพิ่มประสิทธิภาพสามารถเลือกวิธีที่เป็นไปได้มากขึ้นอาจใช้ความเท่าเทียมกันเอาค่าโสหุ้ยจำนวนมากที่มาจากหนึ่งแถวต่อครั้ง
  2. ตรวจสอบให้แน่ใจว่ามีดัชนีที่สนับสนุนงาน บ่อยครั้งที่คำสั่งของการปรับปรุงขนาดอาจมีดัชนีที่ถูกต้องเทียบกับไม่ นี่เป็นเรื่องจริงในหน่วยความจำและด้วยการเข้าถึงดิสก์ กระบวนการยังคงใช้เวลาหลายชั่วโมงกับทุกอย่างใน RAM หากไม่มีดัชนีที่เหมาะสมในชุดข้อมูลขนาดใหญ่
  3. ถัดไปด้วยชุดตรรกะและดัชนีในสถานที่ฉันจะดูว่าหน้าข้อมูลที่ได้รับผลกระทบนั้นพอดีกับหน่วยความจำหรือไม่ ณ จุดนี้หากยังคงมีการเข้าถึงดิสก์จำนวนมากการดูการอ่านทางกายภาพและการทำงานของดิสก์นั้นสมเหตุสมผลเพราะประโยชน์ที่ได้รับจากการปรับให้เหมาะสมทั้งหมดนั้นทำในสองขั้นตอนแรก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.