मैं एक ग्राहक डेटाबेस को पुनः डिज़ाइन कर रहा हूं और सूचना के नए टुकड़ों में से एक जिसे मैं मानक पते फ़ील्ड (स्ट्रीट, सिटी, आदि) के साथ संग्रहीत करना चाहता हूं, वह पते का भौगोलिक स्थान है। मेरे पास केवल एक ही उपयोग मामला है कि उपयोगकर्ताओं को Google मानचित्र पर निर्देशांक को मैप करने की अनुमति दी जाए जब पता अन्यथा नहीं मिल सकता है, जो अक्सर तब होता है जब क्षेत्र नया विकसित होता है, या एक दूरस्थ / ग्रामीण स्थान पर होता है।
मेरा पहला झुकाव अक्षांश और देशांतर को दशमलव मानों के रूप में संग्रहीत करना था, लेकिन फिर मुझे याद आया कि SQL Server 2008 R2 में geography
डेटा प्रकार है। मेरे पास उपयोग करने का बिल्कुल कोई अनुभव नहीं है geography
, और अपने शुरुआती शोध से, यह मेरे परिदृश्य के लिए अधिक महत्वपूर्ण है।
उदाहरण के लिए, अक्षांश और देशांतर के साथ काम करने के लिए, decimal(7,4)
मैं यह कर सकता हूं:
insert into Geotest(Latitude, Longitude) values (47.6475, -122.1393)
select Latitude, Longitude from Geotest
लेकिन इसके साथ geography
, मैं यह करूंगा:
insert into Geotest(Geolocation) values (geography::Point(47.6475, -122.1393, 4326))
select Geolocation.Lat, Geolocation.Long from Geotest
हालांकि ऐसा नहीं है कि और अधिक जटिल है, क्यों ऐड जटिलता अगर मैं करने के लिए नहीं है?
इससे पहले कि मैं उपयोग करने के विचार को छोड़ दूं geography
, क्या ऐसा कुछ है जिस पर मुझे विचार करना चाहिए? क्या स्थानिक सूचकांक बनाम अक्षांश और देशांतर क्षेत्रों का उपयोग करके किसी स्थान की खोज करना तेज़ होगा? क्या इसका उपयोग करने के फायदे हैं geography
जो मुझे ज्ञात नहीं हैं? या, फ्लिप साइड पर, क्या ऐसे कैविएट हैं, जिनके बारे में मुझे पता होना चाहिए कि मुझे उपयोग करने से कौन हतोत्साहित करेगा geography
?
अपडेट करें
@ एरिक फिलिप्स ने निकटता वाली खोजों को करने की क्षमता लाई geography
, जो बहुत ही शांत है।
दूसरी ओर, एक त्वरित परीक्षण यह दिखा रहा है कि select
अक्षांश (देशांतर) प्राप्त करने के लिए एक सरल का उपयोग करते समय काफी धीमा है geography
। , और मुझे एसओ पर एक और एसओ प्रश्न के स्वीकृत उत्तर पर एक टिप्पणी है geography
:
@SaphuA आपका स्वागत है। एक सुन्नत के रूप में एक अशक्त GEOGRAPHY डेटाटाइप कॉलम पर एक स्थानिक सूचकांक का उपयोग करने के लिए बहुत ही उपयोगी है। कुछ गंभीर प्रदर्शन के मुद्दे हैं, इसलिए यह सुनिश्चित करें कि GEOGRAPHY कॉलम नॉन-नॉलेबल है भले ही आपको अपने स्कीमा को फिर से तैयार करना पड़े। - टॉमस जून 18 को 11:18 बजे
सभी सभी में, निकटता की खोज बनाम प्रदर्शन और जटिलता में व्यापार बंद होने की संभावना को तौलते हुए, मैंने geography
इस मामले में उपयोग को त्यागने का फैसला किया है ।
मेरे द्वारा चलाए गए परीक्षण का विवरण:
मैंने दो टेबल बनाई, एक का उपयोग कर geography
और दूसरे का उपयोग decimal(9,6)
अक्षांश और देशांतर के लिए:
CREATE TABLE [dbo].[GeographyTest]
(
[RowId] [int] IDENTITY(1,1) NOT NULL,
[Location] [geography] NOT NULL,
CONSTRAINT [PK_GeographyTest] PRIMARY KEY CLUSTERED ( [RowId] ASC )
)
CREATE TABLE [dbo].[LatLongTest]
(
[RowId] [int] IDENTITY(1,1) NOT NULL,
[Latitude] [decimal](9, 6) NULL,
[Longitude] [decimal](9, 6) NULL,
CONSTRAINT [PK_LatLongTest] PRIMARY KEY CLUSTERED ([RowId] ASC)
)
और प्रत्येक तालिका में समान अक्षांश और देशांतर मानों का उपयोग करके एक एकल पंक्ति सम्मिलित की गई:
insert into GeographyTest(Location) values (geography::Point(47.6475, -122.1393, 4326))
insert into LatLongTest(Latitude, Longitude) values (47.6475, -122.1393)
अंत में, निम्नलिखित कोड चलाने से पता चलता है कि, मेरी मशीन पर, अक्षांश और देशांतर का चयन करते समय लगभग 5 बार धीमी गति से उपयोग किया जाता है geography
।
declare @lat float, @long float,
@d datetime2, @repCount int, @trialCount int,
@geographyDuration int, @latlongDuration int,
@trials int = 3, @reps int = 100000
create table #results
(
GeographyDuration int,
LatLongDuration int
)
set @trialCount = 0
while @trialCount < @trials
begin
set @repCount = 0
set @d = sysdatetime()
while @repCount < @reps
begin
select @lat = Location.Lat, @long = Location.Long from GeographyTest where RowId = 1
set @repCount = @repCount + 1
end
set @geographyDuration = datediff(ms, @d, sysdatetime())
set @repCount = 0
set @d = sysdatetime()
while @repCount < @reps
begin
select @lat = Latitude, @long = Longitude from LatLongTest where RowId = 1
set @repCount = @repCount + 1
end
set @latlongDuration = datediff(ms, @d, sysdatetime())
insert into #results values(@geographyDuration, @latlongDuration)
set @trialCount = @trialCount + 1
end
select *
from #results
select avg(GeographyDuration) as AvgGeographyDuration, avg(LatLongDuration) as AvgLatLongDuration
from #results
drop table #results
परिणाम:
GeographyDuration LatLongDuration
----------------- ---------------
5146 1020
5143 1016
5169 1030
AvgGeographyDuration AvgLatLongDuration
-------------------- ------------------
5152 1022
इससे भी अधिक आश्चर्य की बात यह है कि जब कोई पंक्तियों का चयन नहीं किया जाता है, उदाहरण के लिए RowId = 2
, जहां चयन करना है , जो मौजूद नहीं है, geography
तब भी धीमी थी:
GeographyDuration LatLongDuration
----------------- ---------------
1607 948
1610 946
1607 947
AvgGeographyDuration AvgLatLongDuration
-------------------- ------------------
1608 947