แม้ว่าบทความนี้จะไม่ใช่คำตอบที่สมบูรณ์เนื่องจากขาดข้อมูล แต่ควรสามารถชี้ให้คุณในทิศทางที่เหมาะสมหรือรับข้อมูลเชิงลึกที่คุณสามารถแบ่งปันกับชุมชนได้ในภายหลัง
น่าเสียดายที่คำจำกัดความนี้ส่งผลให้ประสิทธิภาพลดลงตามสถานการณ์ก่อนหน้านี้ด้วยตารางบนดิสก์ ลำดับของขนาดสูงกว่าหรือน้อยกว่า 10% (ในบางกรณีถึง 100% ดังนั้นเวลาสองเท่า)
สิ่งสำคัญที่สุดคือฉันคาดหวังว่าจะได้รับประโยชน์อย่างมากในสถานการณ์ที่เกิดขึ้นพร้อมกันสูงเนื่องจากสถาปัตยกรรมที่ไม่มีการล็อกโฆษณาโดย Microsoft แต่ประสิทธิภาพที่แย่ที่สุดนั้นก็คือเมื่อมีผู้ใช้หลายคนพร้อมกันที่รันคิวรีจำนวนมากบนโต๊ะ
นี่เป็นเรื่องที่หนักใจเพราะไม่ควรเป็นอย่างนั้น ปริมาณงานบางอย่างไม่ได้อยู่ในตารางหน่วยความจำ (SQL 2014) และปริมาณงานบางอย่างให้ยืมด้วยตนเอง ในสถานการณ์ส่วนใหญ่อาจมีการชนน้อยที่สุดเพียงแค่ย้ายและเลือกดัชนีที่เหมาะสม
แต่เดิมฉันคิดมากเกี่ยวกับคำถามของคุณเกี่ยวกับเรื่องนี้:
คำถาม:
- BUCKET_COUNT ที่ถูกต้องที่จะตั้งคืออะไร
- ฉันควรใช้ดัชนีประเภทใด
- เหตุใดประสิทธิภาพจึงแย่กว่าตารางที่ใช้ดิสก์
ตอนแรกฉันเชื่อว่าจะมีปัญหากับจริงในตารางหน่วยความจำและดัชนีไม่เหมาะสม ในขณะที่มีปัญหาบางอย่างเกี่ยวกับการกำหนดดัชนีแฮชที่ปรับให้เหมาะสมหน่วยความจำฉันเชื่อว่าปัญหาจริงที่จะอยู่กับแบบสอบถามที่ใช้
-- INSERT (can vary from 10s to 10,000s of records):
INSERT INTO MyTable
SELECT @fixedValue, id2, col1, col2 FROM AnotherTable
ส่วนแทรกนี้ควรเร็วมากหากเกี่ยวข้องกับตารางหน่วยความจำในเท่านั้น อย่างไรก็ตามยังเกี่ยวข้องกับตารางที่ยึดตามดิสก์และขึ้นอยู่กับการล็อคและการบล็อกทั้งหมดที่เกี่ยวข้อง ดังนั้นของเสียแบบเรียลไทม์ที่นี่จึงอยู่บนตารางพื้นฐานของดิสก์
เมื่อฉันทำการทดสอบอย่างรวดเร็วกับการแทรกแถว 100,000 จากตารางบนดิสก์หลังจากโหลดข้อมูลลงในหน่วยความจำ - มันเป็นเวลาตอบสนองย่อยที่สอง อย่างไรก็ตามข้อมูลส่วนใหญ่ของคุณจะถูกเก็บไว้ในระยะเวลาสั้น ๆ น้อยกว่า 20 วินาทีเท่านั้น นี่ไม่ได้ให้เวลากับการแคชจริงมากนัก นอกจากนี้ฉันไม่แน่ใจว่ามีขนาดใหญ่AnotherTable
จริง ๆ และไม่รู้ว่าค่านั้นถูกอ่านจากดิสก์หรือไม่ เราต้องพึ่งพาคุณสำหรับคำตอบเหล่านี้
ด้วยแบบสอบถามเลือก:
SELECT id2, col1
FROM MyTable INNER JOIN OtherTbl ON MyTable.id2 = OtherTbl.pk
WHERE id1 = @value
ORDER BY col1
อีกครั้งเราอยู่ในความเมตตาของประสิทธิภาพการทำงานของตารางที่อิงกับดิสก์ นอกจากนี้การเรียงลำดับไม่ถูกในดัชนี HASH และควรใช้ดัชนีที่ไม่เป็นคลัสเตอร์ สิ่งนี้ถูกเรียกใช้ในคู่มือดัชนีที่ฉันเชื่อมโยงในความคิดเห็น
เพื่อให้ข้อเท็จจริงตามการวิจัยจริง ๆ ฉันได้โหลดSearchItems
ตารางหน่วยความจำที่มี 10 ล้านแถวและAnotherTable
100,000 เพราะฉันไม่ทราบขนาดหรือสถิติที่แท้จริงของมัน ฉันใช้แบบสอบถามแบบเลือกด้านบนเพื่อดำเนินการ นอกจากนี้ฉันสร้างเซสชันเพิ่มเติมของกิจกรรมบน wait_completed และใส่ลงในบัฟเฟอร์วงแหวน มันถูกทำความสะอาดหลังการวิ่งแต่ละครั้ง ฉันยังวิ่งDBCC DROPCLEANBUFFERS
ไปจำลองสภาพแวดล้อมที่ข้อมูลทั้งหมดอาจไม่อยู่ในหน่วยความจำ
ผลลัพธ์ไม่ได้มีอะไรน่าตื่นเต้นเมื่อมองดูพวกเขาในสุญญากาศ เนื่องจากแล็ปท็อปที่ฉันกำลังทดสอบนี้ใช้ SSD ระดับสูงกว่าฉันจึงลดประสิทธิภาพการทำงานของดิสก์ลงสำหรับ VM ที่ฉันใช้
ผลลัพธ์ที่ได้นั้นมาพร้อมกับข้อมูลที่ไม่ต้องรอหลังจากทำการสืบค้น 5 ครั้งบนตารางที่อยู่ในหน่วยความจำ (ลบการเข้าร่วมและไม่มีการสืบค้นย่อย) นี่มันสวยมากอย่างที่คาดไว้
อย่างไรก็ตามเมื่อใช้ข้อความค้นหาดั้งเดิมฉันก็รออยู่ ในกรณีนี้มันคือ PAGEIOLATCH_SH ซึ่งสมเหตุสมผลเมื่อข้อมูลกำลังถูกอ่านจากดิสก์ เนื่องจากฉันเป็นผู้ใช้คนเดียวในระบบนี้และไม่ได้ใช้เวลาในการสร้างสภาพแวดล้อมการทดสอบขนาดใหญ่สำหรับส่วนแทรกการปรับปรุงการลบกับตารางที่เข้าร่วมฉันไม่ได้คาดหวังว่าการล็อกหรือการบล็อกจะมีผล
ในกรณีนี้อีกครั้งส่วนเวลาที่สำคัญถูกใช้ในตารางตามดิสก์
ในที่สุดแบบสอบถามลบ การค้นหาแถวที่อิงจาก ID1 นั้นไม่ได้มีประสิทธิภาพมากนักเมื่อมีดัชนี ในขณะที่มันเป็นความจริงที่ภาคแสดงความเท่าเทียมกันเป็นสิ่งที่ดัชนีแฮชเหมาะสมสำหรับถังข้อมูลที่อยู่ในนั้นขึ้นอยู่กับคอลัมน์ที่แฮชทั้งหมด ดังนั้น id1, id2 โดยที่ id1 = 1, id2 = 2 และ id1 = 1, id2 = 3 จะถูกแฮ็กเข้าไปในที่เก็บข้อมูลที่แตกต่างกันเนื่องจากแฮชจะข้าม (1,2) และ (1,3) นี่จะไม่ใช่การสแกนช่วง B-Tree อย่างง่ายเนื่องจากดัชนีแฮชไม่ได้มีโครงสร้างแบบเดียวกัน ฉันคาดหวังว่าสิ่งนี้จะไม่เป็นดัชนีในอุดมคติสำหรับการดำเนินการนี้ แต่ฉันไม่คาดหวังว่าจะได้รับคำสั่งที่มีขนาดยาวกว่าที่มีประสบการณ์ ฉันสนใจที่จะเห็น wait_info เกี่ยวกับเรื่องนี้
สิ่งสำคัญที่สุดคือฉันคาดหวังว่าจะได้รับประโยชน์อย่างมากในสถานการณ์ที่เกิดขึ้นพร้อมกันสูงเนื่องจากสถาปัตยกรรมที่ไม่มีการล็อกโฆษณาโดย Microsoft แต่ประสิทธิภาพที่แย่ที่สุดนั้นก็คือเมื่อมีผู้ใช้หลายคนพร้อมกันที่รันคิวรีจำนวนมากบนโต๊ะ
ในขณะที่มันเป็นความจริงที่ใช้ล็อคเพื่อความมั่นคงตรรกะการดำเนินการจะต้องยังคงเป็นอะตอม สิ่งนี้ทำผ่านตัวดำเนินการเปรียบเทียบ CPU แบบพิเศษ (ซึ่งเป็นสาเหตุที่ In-Memory ทำงานได้เฉพาะกับ [บางตัวแม้ว่าซีพียูเกือบทุกตัวที่ทำใน 4 ปีที่ผ่านมา]) ดังนั้นเราจะไม่ได้รับทุกอย่างฟรีจะมีเวลาในการดำเนินการเหล่านี้ให้เสร็จ
อีกประเด็นที่จะนำมาเป็นความจริงที่ว่าในเกือบทุกแบบสอบถามที่ใช้อินเตอร์เฟซที่เป็น T-SQL (และไม่ได้รวบรวม SPROCs) ซึ่งสัมผัสอย่างน้อยหนึ่งตารางตามดิสก์ นี่คือเหตุผลที่ฉันเชื่อว่าในท้ายที่สุดเราไม่ได้มีประสิทธิภาพเพิ่มขึ้นจริง ๆ เพราะเรายังคง จำกัด ประสิทธิภาพของตารางที่ใช้ดิสก์
ติดตาม:
สร้างเซสชันเหตุการณ์เพิ่มเติมสำหรับ wait_completed และระบุ SPID ที่คุณรู้จัก เรียกใช้แบบสอบถามและให้ผลลัพธ์กับเราหรือใช้ภายใน
ให้เราอัปเดตเกี่ยวกับผลลัพธ์จาก # 1
ไม่มีหมายเลขเวทมนต์สำหรับการพิจารณาจำนวนนับสำหรับดัชนีแฮช โดยทั่วไปตราบใดที่ถังไม่เต็มและโซ่แถวอยู่ต่ำกว่า 3 หรือ 4 ประสิทธิภาพควรอยู่ในระดับที่ยอมรับได้ นี่เป็นการถามแบบ "ฉันควรตั้งค่าไฟล์บันทึกของฉันเป็นอย่างไร" - มันจะขึ้นอยู่กับกระบวนการต่อฐานข้อมูลต่อประเภทการใช้งาน
OPTION(OPTIMIZE FOR UNKNOWN)
(ดูคำแนะนำตาราง ) หรือไม่