2009-08-27 8 views
7

Mam aplikację, w której zasadniczo mam ogromną tabelę (100 milionów rekordów) informacji, z każdym wierszem zawierającym wartość lat/długą.Czy funkcje danych przestrzennych programu SQL Server 2008 są przydatne do mapowania zapytań?

Ciągle wyszukuję tę tabelę, aby uzyskać wszystkie rekordy mieszczące się w promieniu wokół pewnego punktu. Na przykład: "wszystkie rekordy w odległości 5 mil od 39,89288, -104,1919434"

W tym celu mam indeks nad kolumnami Lat/Long i otrzymuję "kwadrat ograniczający" punktów, a następnie odrzucam wszystkie punkty, które wypadają poza okręgiem w mojej aplikacji ASP.Net, ponieważ było to szybsze niż wykonywanie obliczeń koła w SQL Server.
UWAGA: To są wszystkie dane dotyczące Stanów Zjednoczonych, więc uważam, że ziemia jest płaska dla moich obliczeń, która jest wystarczająco dokładna dla moich potrzeb.

Główny problem z indeksem Lat/Long polega na tym, że jest to "kwadrat" punktów, a ponieważ próbuję znaleźć "Lat między X i Y" i "Długi między X i Y", nie może tak naprawdę używać tego indeksu super-wydajnie, jak mogłoby to być, gdybym szukał "linii" punktów.

Czytałem o cechach przestrzennych SQL 2008, ale nie znalazłem wystarczająco konkretnych informacji, aby wiedzieć, czy jest to dla mnie przydatne.

Pytanie brzmi: czy SQL 2008 ma jakiś inny rodzaj indeksu, który sprawi, że ten typ zapytania będzie dużo szybszy niż w SQL 2005?

+0

Dobre pytanie! Zrobiłem coś bardzo podobnego do tego, co robisz teraz w SQL2005, więc chciałbym usłyszeć, co ludzie wymyślą –

Odpowiedz

3

Znalazłem to:

dla SQL 2008:
http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/sql-server-2008-proximity-search-with-th

Podobno jest to możliwe

UWAGA: Wersja tego artykułu SQL 2005 nie działa zbyt dobrze. Próbowałem tego rodzaju rzeczy i lepiej jest po prostu uzyskać kwadrat z SQL Server, a następnie wyciąć koła w swoim własnym kodem.

więcej linków atrakcji:

http://msdn.microsoft.com/en-us/library/bb964712.aspx
(wreszcie wyjaśnienie !!)

I kwerendy próbka ... Najwyraźniej jest to, jak to zrobić wyszukiwanie chcę (punkty w ciągu 5 -mile okręgu)

DECLARE @Location GEOGRAPHY 
SET @Location = GEOGRAPHY::STPointFromText('POINT(73.9517061 40.7934358)',4326).STBuffer(5 * 1600); 
SELECT [fields] FROM [table] WHERE LocGeog.STIntersects(@Location) = 1 

(LocGeog jest kolumna geografii)

O dziwo, to działa wolniej niż moje stare, stare zapytanie (7 razy wolniej), więc oczywiście wciąż robię coś bardzo nie tak.

1

Tak, można to zrobić bardzo dobrze z danymi przestrzennymi SQL 2008. Istnieje pewna wiedza/próba i błąd (?) W ustawianiu indeksowania przestrzennego na właściwym poziomie siatki, ale potem przypuszcza się, że jest świetny (przekazany mi przez przyjaciół, sam nie używałam go do produkcji).

Dla swoich celów (szer/dł) będzie wan GEO graficzny rodzaj i nie geo metryczny.Uważam, że indeksy przestrzenne ustawiają indeksowanie typu "zagnieżdżony trójkąt ograniczający", co stanowi ulepszenie w porównaniu z typem wstępnym "ograniczającego pola", którego zmuszeni jesteśmy wykonywać w SQL bez niego.

OK, proponuję zacząć od this post na blogu "Domu strasznego DBA" Granta Fritcheya (powiedz mu, że wysłałem ci, jeśli chcesz zadać pytania :-)). Jest to dobre wytłumaczenie niektórych analiz wydajności, które właśnie zaczął się uczyć, a także zawiera łącza do wielu innych materiałów.

5

Tak! Sprawdź this article o indeksach przestrzennych. Zobaczysz, że tego typu indeksy działają lepiej niż podejście "indeks indeksowany". Poza tym nie tylko będziesz w stanie efektywnie wyszukiwać "jest punkt w pobliżu innego punktu", ale także wszystkie inne rodzaje operacji geograficznych. Here's pełna lista wszystkich dostępnych metod na typie.

0

wiesz, robiłem lat/Długość geograficzna zapytań w Starbucks około 5 lat temu ...

iw zasadzie chcieliśmy korelują sklepów do centrów dystrybucyjnych .. Pracowałem w swoim dziale operacyjnym, a oni Szczerze mówiąc nie mogłem powiedzieć, który sklep został dostarczony przez konkretny magazyn.

Więc skończyłem wymyślić ten algorytm "magicznego kręgu".

zasadzie, mieli kilka zapytań, który wyglądał tak: select * from Tabela1, tabela2 Gdzie UdfDistance (table1.Lat, table1.Long, table2.Lat, table2.Long)> = 250

Skończyło się na tym, że zbliżałem się do czegoś NAPRAWDĘ podobnego, ale działało o wiele szybciej

wybierz * z tabeli 1, tabeli 2 Gdzie UdfDistance (table1.Lat, table1.Long, table2.lat, table2.Long)> = 250 table1.Lat between (table2.lat - 1) i (table2.lat + 1) i table1. Długość pomiędzy (table2.Long - 1) i (table2.Long + 1)

Zasadniczo - nie próbuj porównywać dwóch punktów geograficznych, jeśli różnica między nimi jest większa niż 1 stopień (różna i długa).

Innymi słowy- użył NORMALNYCH INDEKSÓW RELACYJNYCH, aby odfiltrować wiele wartości, a następnie obliczenia odległości UDF miały o wiele mniej informacji do przetworzenia.

Mam nadzieję, że pomoże, postaram się wyjaśnić, czy muszę odpowiedzieć na pytanie:

Powiązane problemy