วิธีเพิ่มประสิทธิภาพของแบบสอบถามเพื่อให้ค้นหาในดัชนีหนึ่งก่อนจากนั้นจึงสร้างดัชนีอื่นหลังจากนั้น


12

ฉันมีการวัดโลกสองชุดจากข้อมูลดาวเทียมแต่ละชุดมีเขตเวลา (mjd สำหรับค่าจูเลียนเฉลี่ย) และตำแหน่งทางภูมิศาสตร์ (GeoPoint, spacial) และฉันกำลังมองหาความบังเอิญระหว่างสองชุดดังกล่าวซึ่งเวลาของพวกเขาตรงกับเกณฑ์ของ 3 ชั่วโมง (หรือ .125 วัน) และระยะทางของพวกเขาภายใน 200 กม. ของกันและกัน

ฉันสร้างดัชนีสำหรับทั้งฟิลด์ mjd บนทั้งตารางและตารางเชิงพื้นที่

เมื่อฉันเพิ่งเข้าร่วมในข้อ จำกัด เวลาฐานข้อมูลจะคำนวณการแข่งขัน 100,000 ครั้งใน 8 วินาทีและคำนวณระยะทางสำหรับการแข่งขันทั้งหมด 100,000 ครั้งในเวลานั้น แบบสอบถามมีลักษณะดังนี้:

select top 100000 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
option( table hint ( h, index(ix_MJD) ), table hint( m, index(ix_MJD) ) )

และแผนดำเนินการคือ:

ข้อ จำกัด mjd เท่านั้น

เมื่อเรียงลำดับแล้ว 9 จากระยะทางอยู่ต่ำกว่า 200 กม. ดังนั้นจึงมีการแข่งขัน ปัญหาคือเมื่อฉันเพิ่มข้อ จำกัด ระยะทางและรันสิ่งนี้แทน

select top 10 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
and h.GeoPoint.STDistance(m.GeoPoint)<200000
option( table hint ( h, index(ix_MJD) ), table hint( m, index(ix_MJD) ) )

มันหายไปเป็นเวลานาน เห็นได้ชัดว่าใน 8 วินาทีสามารถค้นหาการแข่งขันได้ 100,000 ครั้งโดย 9 ในนั้นอยู่ต่ำกว่า 200 กมดังนั้นเครื่องมือเพิ่มประสิทธิภาพจะต้องพยายามทำบางสิ่งที่ดีที่สุด แผนมีลักษณะคล้ายกับด้านบนพร้อมตัวกรองสำหรับระยะทาง (ฉันคาดเดา)

ด้วยข้อ จำกัด เชิงพื้นที่ไม่มีตัวกรองเชิงพื้นที่

ฉันสามารถบังคับใช้ดัชนีอวกาศด้วยสิ่งนี้:

select top 5 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0 
from L2V5.dbo.header h join L2.dbo.MLS_Header m 
on h.GeoPoint.STDistance(m.GeoPoint)<200000
and h.mjd between m.mjd-.125 and m.mjd+.125 
option( table hint ( h, index(ix_MJD), index(ix_GeoPoint) ), table hint( m, index(ix_MJD) ) )

ข้อ จำกัด ทั้งกับดัชนีทั้งสอง

ซึ่งจะใช้เวลา 3 นาทีในการค้นหา 5 แมทช์

ฉันจะบอกให้เคียวรีเครื่องมือเพิ่มประสิทธิภาพใช้ดัชนี MJD ค้นหาก่อนจากนั้นดัชนีปริภูมิที่สอง (หรือคือสิ่งที่ทำไปแล้ว) และมีวิธีใดที่ฉันสามารถช่วยได้ หากสามารถคำนวณการแข่งขัน 100,000 นัดด้วยระยะทางใน 8 วินาทีที่มี 9 ใต้ 200 กม. การเพิ่มดัชนีอวกาศไม่ควรทำให้เร็วขึ้นหรือไม่ช้าลง?

ขอบคุณสำหรับเคล็ดลับหรือความคิดเห็นอื่น ๆ

แก้ไข: เพื่อตอบคำถามว่าแผนดูเหมือนอย่างไรโดยไม่มีคำแนะนำนี้ (และมันต้องใช้ตลอดไป):

ไม่มีคำใบ้

นอกจากนี้ยังอาจกล่าวถึงว่ามีเกือบ 1 ล้านระเบียนในตารางหนึ่งและอีก 8 ล้านบันทึก


แผนคิวรีของคุณมีลักษณะอย่างไรหากคุณลบคำแนะนำเหล่านั้นออก
Zane

@ Zane ฉันแก้ไขโพสต์และเพิ่มแผนคิวรีแบบไม่มีคำใบ้ มันจะแทนที่การค้นหาด้วยการสแกนและเวลานั้นสุดเหวี่ยง
261963

คำตอบ:


6

ปัญหาคือมันอาจ (และรู้ดัชนีอวกาศอาจจะ) คิดว่าตัวกรองเชิงพื้นที่จะเลือกมากขึ้นกว่าตัวกรองเวลา

แต่ถ้าคุณมีไม่กี่ล้านบันทึกภายใน 200km ก็อาจจะแย่ลงอย่างมีนัยสำคัญ

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

หรืออื่น ๆ ที่คุณค้นหาระเบียนตามเวลาและคุณได้ผลลัพธ์ตามเวลา จากนั้นการกรองรายการนี้ไปยังรัศมี 200km เป็นเรื่องของการตรวจสอบแต่ละรายการ

หากคุณกรองข้อมูลในสองช่วงเช่นนี้จะเป็นการยากที่จะใช้ตัวกรองที่สองโดยใช้ดัชนี คุณอาจจะดีกว่าบอกว่าอย่าใช้ดัชนีอวกาศถ้าตัวกรองเวลาเป็นตัวกรองที่เข้มงวดมากขึ้น

หากทั้งคู่มีขนาดใหญ่และมันก็อยู่ด้วยกันอย่างแน่นหนาคุณก็จะมีปัญหาที่ซับซ้อนมากขึ้นคนที่พยายามแก้ไขเป็นเวลานานและสามารถแก้ไขได้โดยดัชนีที่ครอบคลุม 3D (และอื่น ๆ ) ช่องว่าง ยกเว้นว่า SQL Server ไม่มีอยู่

ขอโทษ

แก้ไข: ข้อมูลเพิ่มเติม ...

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

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

ดังนั้นคุณเหลือสถานการณ์ที่น่าอึดอัดใจฉันกลัว :(

แก้ไข: ลอง:

select top 100000 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
where h.GeoPoint.STDistance(m.GeoPoint)/1000.0 < 200
option( table hint ( h, index(ix_MJD) ) );

สังเกตุว่าฉันตั้งใจแบ่งความสามารถในการ sargability โดยหารด้วย 1,000 ก่อนที่จะเปรียบเทียบกับ 200 ฉันต้องการให้งานนี้ทำในการค้นหาคีย์

โปรดทราบว่าคุณสามารถหลีกเลี่ยงความต้องการการค้นหา (และคำแนะนำ) ได้โดยการรวม GeoPoint และ Time ในดัชนี ix_MJD แน่นอนว่าจะนำความร้อนออกจากแผนแบบสอบถาม


ฉันไม่รู้ว่ามันเปลี่ยนแปลงอะไรหรือไม่ แต่ตัวกรองเวลาเลือกได้มากกว่า
261963

ตกลง. ดังนั้นจึงเป็นที่ยอมรับหรือไม่ที่จะค้นหาแถวที่จับคู่เวลาทั้งหมดแล้วตรวจสอบแต่ละตำแหน่งโดยไม่มีดัชนี
Rob Farley

... ดังนั้นแผนดูเหมือนของเดิม แต่มีภาคแสดงหรือตัวกรองพิเศษ
Rob Farley

แนะนำการเปลี่ยนแปลงบางอย่างด้วยการแก้ไขอย่างรวดเร็ว คุณไม่จำเป็นต้องบอกใบ้เกี่ยวกับ m เพียงแค่ h แม้ว่าคุณจะสามารถสลับได้ว่าอันไหนที่คุณเพิ่มเข้าไป 1/8 แต่เพื่อให้แน่ใจว่าคุณกำลังแก้ไขคอลัมน์จากตารางที่เล็กกว่าและใช้ค่าเหล่านั้นเพื่อค้นหาสิ่งที่ใหญ่กว่านั่นก็จะช่วยได้เช่นกัน หาก h คือ 8M และ m คือ 1M ออกจากเพรดิเคต BETWEEN และให้คำใบ้สำหรับ h หากเป็นอีกวิธีหนึ่งให้เปลี่ยนเพรดิเคตและคำใบ้ของคุณ (แต่ดีกว่าการเปลี่ยนคำใบ้คือการเพิ่มคอลัมน์เหล่านั้นในดัชนีของคุณ)
Rob Farley

การทำตามคำแนะนำของตารางทั้งหมดดูเหมือนว่าจะทำงานได้ดีที่สุดในท้ายที่สุดตราบใดที่ฉันอยู่ระหว่าง m และไม่ใช่วิธีอื่น ๆ แบบสอบถามไม่ใช้ดัชนี GeoPoint อีกต่อไป แต่จะไม่ใช้ดัชนีอย่างมีประสิทธิภาพ ฉันรวมคอลัมน์ GeoPoint ไว้ในดัชนี MJD และนั่นช่วยได้มาก select top 10000 h.Time, m.Time, m.GeoPoint.STDistance(h.GeoPoint), h.mjd-m.mjd from L2V5.dbo.header h join L2.dbo.MLS_Header m on m.GeoPoint.STDistance(h.GeoPoint)<200000 and m.mjd between h.mjd-.125 and h.mjd+.125 order by h.mjd
261963
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.