Optimalkan permintaan tetangga terdekat pada cloud 70 juta titik di SQL Server 2008

16

Saya memiliki sekitar 75 juta catatan dalam database SQL Server 2008 R2 Express. Masing-masing panjang lat terkait dengan beberapa nilai. Tabel memiliki kolom geografi. Saya mencoba menemukan tetangga terdekat untuk garis bujur lintang (titik) tertentu. Saya sudah memiliki kueri dengan indeks spasial di tempat. Tetapi tergantung pada di mana catatan berada dalam database, katakanlah kuartal pertama atau kuartal terakhir, kueri dapat memakan waktu sekitar 3 hingga 30 detik untuk menemukan tetangga terdekat. Saya merasa ini dapat dioptimalkan untuk memberikan hasil yang jauh lebih cepat dengan mengoptimalkan kueri atau indeks spasial. Sekarang menerapkan beberapa indeks spasial dengan pengaturan default. Berikut ini tabel dan kueri saya.

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]

Indeks spasial yang saya gunakan:

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]

Inilah Query yang saya gunakan:

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

Berikut ini adalah contoh lat long dalam database saya. untuk memberikan gagasan tentang akurasi dan kepadatan. Semua 70 juta catatan adalah untuk satu kota (data Lidar).

POINT (-95.669434934023087 30.049513838913736)

Sekarang kueri ini memberi saya hasil seperti yang saya jelaskan di atas, tetapi saya ingin meningkatkan kinerja sebanyak mungkin. Dugaan saya adalah dengan mengubah nilai default indeks spasial saya mungkin di atas untuk mengoptimalkan kinerja dengan lebih baik. Ada petunjuk tentang ini?

Saya mencoba memvariasikan buffer dari 10 hingga 1000 tetapi dengan hasil yang hampir sama.

Juga ada saran lain untuk meningkatkan kinerja.

Inilah sistem yang saya gunakan saat ini:

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
Shaunak
sumber
1
Apakah ini data LIDAR? Jika demikian pertimbangkan untuk menambahkan lidartag.
Kirk Kuykendall
2
Saya tidak berbicara SQL Server, tetapi bagi saya mata saya belum mengetahui bahwa kueri Anda harus menemukan semua titik yang berada dalam buffer 1000 meter dari titik target. Tes titik-dalam-poligon ini akan menjadi jauh lebih lambat daripada tes kedekatan, yang merupakan dasar untuk solusi yang ditawarkan dalam pertanyaan Anda sebelumnya .
whuber
@whuber: Saya telah mencoba kueri berbasis jarak dan waktu dalam hitungan menit. jalan ke tinggi. Mungkin saya salah di suatu tempat. Pada titik ini dalam poligon, dibutuhkan waktu dalam detik. Bahkan memvariasikan buffer dari 10 hingga 10.000 memiliki sedikit dampak pada waktunya.
Shaunak
1
@Shaunak Lalu ada sesuatu masalah dengan pertanyaan berbasis jarak, karena secara teoritis mereka dapat dilakukan rata-rata dalam mikrodetik (atau lebih baik) dan dalam milidetik (kasus terburuk) menggunakan indeks yang sesuai seperti pohon KD . Anda mungkin ingin memikirkan untuk meningkatkannya daripada mencari cara untuk mengoptimalkan pencarian point-in-buffer.
whuber
Apakah ini data kisi? Mengapa tidak menggunakan raster?
Matthew Snape

Jawaban:

9

Coba jalankan prosedur tersimpan sp_help_spatial_geography_index untuk mendapatkan detail tentang bagaimana indeks spasial Anda digunakan. Anda harus dapat menggunakan sesuatu seperti:

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;

Posting hasil dalam pertanyaan Anda untuk melihat apakah ada yang menonjol. Arti untuk masing-masing item dapat ditemukan di sini .

Jika koordinat Anda diproyeksikan maka Anda juga bisa melakukan kueri non-spasial sederhana pada bidang X yang dihitung, Y, dan memeriksa X <MinX dan X> MaxX dll.

Memproyeksikan koordinat Anda (dalam bidang tipe GEOMETRI) juga memungkinkan Anda untuk membatasi indeks spasial Anda sejauh data yang dapat mempercepat kinerja jauh. Ganti luasan dunia dengan luasan data Anda:

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]
geografi
sumber
1
Menurut technet.microsoft.com/en-us/library/bb934196.aspx BOUNDING_BOX hanya dapat digunakan untuk GEOMETRY_GRID, tidak GEOGRAPHY_GRID
Kelso
1
Jawaban yang diperbarui. Jenis GEOMETRI harus jauh lebih cepat karena BOUNDING_BOX dapat diatur.
geografi
1

Pertimbangkan untuk menyederhanakan buffer dengan BufferwithTolerance . Jika poin dikemas dengan ketat, sistem harus mengidentifikasi jika suatu titik berada di kedua sisi batas. Semakin sederhana garis itu, semakin sedikit pekerjaan yang harus dilakukan mesin.

Matthew Snape
sumber