ปรับการค้นหาเพื่อนบ้านที่ใกล้เคียงที่สุดบนจุดคลาวด์ 70 ล้านจุดบน SQL Server 2008


16

ฉันมีระเบียนประมาณ 75 ล้านระเบียนในฐานข้อมูล SQL Server 2008 R2 Express แต่ละรายการมีความยาว lat ที่สอดคล้องกับค่าบางค่า ตารางมีคอลัมน์ภูมิศาสตร์ ฉันกำลังพยายามหาเพื่อนบ้านที่ใกล้ที่สุดหนึ่งแห่งสำหรับละติจูดลองจิจูดที่ระบุ (จุด) ฉันมีข้อความค้นหาที่มีดัชนีเชิงพื้นที่อยู่แล้ว แต่ขึ้นอยู่กับตำแหน่งที่บันทึกในฐานข้อมูลพูดในไตรมาสแรกหรือไตรมาสที่แล้วแบบสอบถามอาจใช้เวลาประมาณ 3 ถึง 30 วินาทีในการค้นหาเพื่อนบ้านที่ใกล้ที่สุด ฉันรู้สึกว่าสิ่งนี้สามารถปรับให้เหมาะสมเพื่อให้ได้ผลลัพธ์ที่รวดเร็วยิ่งขึ้นด้วยการปรับการสืบค้นหรือดัชนีเชิงพื้นที่ ตอนนี้ใช้ดัชนีอวกาศด้วยการตั้งค่าเริ่มต้น นี่คือลักษณะตารางและข้อความค้นหาของฉัน

CREATE TABLE lidar(
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [POINTID] [int] NOT NULL,
    [GRID_CODE] [numeric](17, 8) NULL,
    [geom] [geography] NULL,
 CONSTRAINT [PK_lidar_1] PRIMARY KEY CLUSTERED ([id] ASC)
 WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
 ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

ดัชนีเชิงพื้นที่ที่ฉันใช้:

CREATE SPATIAL INDEX [SPATIAL_lidar] ON [dbo].[lidar] ([geom]) USING  GEOGRAPHY_GRID 
WITH (
GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM), 
CELLS_PER_OBJECT = 16, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF,  
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

นี่คือคำค้นหาที่ฉันใช้:

declare @ms_at geography = 'POINT (-95.66 30.04)';
select TOP(1) nearPoints.geom.STAsText()as latlon 
from
(
select r.geom
from lidar r With(Index(SPATIAL_lidar))
where r.geom.STIntersects(@ms_at.STBuffer(1000)) = 1
) nearPoints

นี่คือตัวอย่างของ lat longs ในฐานข้อมูลของฉัน เพื่อให้ทราบถึงความแม่นยำและความหนาแน่น ทั้งหมด 70 ล้านระเบียนมีไว้สำหรับหนึ่งเมือง (ข้อมูล Lidar)

POINT (-95.669434934023087 30.049513838913736)

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

ฉันพยายามเปลี่ยนบัฟเฟอร์จาก 10 เป็น 1,000 แต่ให้ผลลัพธ์เกือบเหมือนกัน

นอกจากนี้ยังมีข้อเสนอแนะอื่น ๆ เพื่อปรับปรุงประสิทธิภาพอีกด้วย

นี่คือระบบที่ฉันใช้อยู่ตอนนี้:

Windows 7 64bit Professional
Intel(R) Core(TM)2 Quad CPU    Q9650  @ 3.00GHz (4 CPUs), ~3.0GHz
Ram: 8 GB
NVIDIA GeForce 9500 GT

1
นี่คือข้อมูล lidar หรือไม่ หากเป็นเช่นนั้นให้พิจารณาเพิ่มlidarแท็ก
Kirk Kuykendall

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

@whuber: ฉันลองใช้ข้อความค้นหาตามระยะทางและเวลาเป็นนาที วิธีการสูง อาจเป็นเพราะฉันจะผิดบางที่ ณ จุดเหล่านี้เป็นรูปหลายเหลี่ยมมันต้องใช้เวลาเป็นวินาที แม้การเปลี่ยนบัฟเฟอร์จาก 10 ถึง 10,000 ก็มีผลต่อเวลาเพียงเล็กน้อย
Shaunak

1
@Shaunak จากนั้นก็มีบางสิ่งบางอย่างเรื่องที่มีคำสั่งตามระยะทางเพราะในทางทฤษฎีที่พวกเขาสามารถทำได้โดยเฉลี่ยใน microseconds (หรือดีกว่า) และในหน่วยมิลลิวินาที (กรณีที่เลวร้าย) โดยใช้ดัชนีที่เหมาะสมเช่นต้นไม้ KD คุณอาจต้องการคิดปรับปรุงพวกเขาแทนที่จะมองหาวิธีเพิ่มประสิทธิภาพการค้นหาจุดในบัฟเฟอร์
whuber

เป็นข้อมูลกริดนี้หรือไม่ ทำไมไม่ใช้แรสเตอร์?
Matthew Snape

คำตอบ:


9

ลองเรียกใช้กระบวนงานที่เก็บไว้sp_help_spatial_geography_indexเพื่อรับรายละเอียดเกี่ยวกับวิธีการใช้ดัชนีเชิงพื้นที่ของคุณ คุณควรใช้สิ่งต่อไปนี้:

declare @ms_at geography = 'POINT (-95.66 30.04)'
set @ms_at = @ms_at.STBuffer(1000).STAsText()
exec sp_help_spatial_geography_index 'lidar', 'SPATIAL_lidar', 0, @ms_at;

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

หากฉายพิกัดของคุณแล้วคุณสามารถทำแบบสอบถามที่ไม่ใช่เชิงพื้นที่ง่ายๆในเขตข้อมูล X, Y ที่คำนวณและตรวจสอบ X <MinX และ X> MaxX เป็นต้น

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

CREATE SPATIAL INDEX [SPATIAL_lidar] ON [dbo].[lidar] ([geom]) USING  GEOMETRY_GRID 
WITH (
GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM), 
CELLS_PER_OBJECT = 16, PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF,  
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON,
BOUNDING_BOX =(-90, -180, 90, 180),) ON [PRIMARY]

1
ตามtechnet.microsoft.com/en-us/library/bb934196.aspx BOUNDING_BOX เท่านั้นที่สามารถใช้สำหรับการ GEOMETRY_GRID ไม่ GEOGRAPHY_GRID
เคล

1
อัปเดตคำตอบ ประเภท GEOMETRY น่าจะเร็วกว่านี้เนื่องจากสามารถตั้งค่า BOUNDING_BOX ได้
geographika

1

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


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