2014-02-10 1 views
0

지형 필드가 불규칙한 모양입니다. 지리 분야는 해당 모양을 정의하는 위도/경도의 백에서 수천까지 다양 할 수 있습니다. 크기에 관해서는 그것은 몇 명의 미국인에게서 일 수 있었다. 미국 전체 주 크기의 우편 번호. 성능 향상을 위해 해당 필드에 Spacial 인덱스를 작성했습니다. 자주 나는 특정 지역 내에있는 위도/경도를 기반으로 한 차량을 찾아야합니다.Geography 필드에서 위도와 경도의 Max, Min을 얻는 다른 방법은 무엇입니까?

내 원래의 접근 방식은 이것이었습니다.

WITH LastP 
      AS (SELECT vlp.ID 
        ,GEOGRAPHY::STPointFromText('POINT(' + CAST(vlp.Long AS VARCHAR(20)) + ' ' 
               + CAST(vlp.Lat AS VARCHAR(20)) + ')', 4326) AS LastKnownPoint 
       FROM LastPosition AS vlp) 
    SELECT lp.ID 
      ,zn.ZONE 
     FROM dbo.GeogZone AS zn WITH (NOLOCK) 
     JOIN @zones AS z 
      ON zn.Zone = z.Zone 
     JOIN LastP AS lp 
      ON lp.LastKnownPoint.STWithin(zn.ZoneGeog) = 1 

나는 나의 테이블 LastPosition에서 모든 레코드를 받고 있었고, 난 Geography 점으로 위도/경도 변환보다 나중에 JOINSTWithin 기능을 사용. 이 과정은 훌륭하지만 매우 느릴 수 있습니다. Spacial 인덱스를 조정하려고했지만 큰 변화는 없었습니다.

성능을 향상 시키려면 다음 프로세스를 소개하고 싶습니다.

지형 유형에서 나는 NorthLat, SouthLat, EastLong, WestLong 을 추출 할 예정입니다. 다음은 비교하기 전에 결과 수를 제한 할 수 있습니다.

WITH LastP 
      AS (SELECT vlp.ID 
        ,GEOGRAPHY::STPointFromText('POINT(' + CAST(vlp.Long AS VARCHAR(20)) + ' ' 
               + CAST(vlp.Lat AS VARCHAR(20)) + ')', 4326) AS LastKnownPoint 
       FROM LastPosition AS vlp 
       WHERE (vlp.Long BETWEEN @WestLong and @EastLong) AND (vlp.Lat BETWEEN @SouthLat AND @NorthLat)) 
    SELECT lp.ID 
      ,zn.ZONE 
     FROM dbo.GeogZone AS zn 
     JOIN @zones AS z 
      ON zn.Zone = z.Zone 
     JOIN LastP AS lp 
      ON lp.LastKnownPoint.STWithin(zn.ZoneGeog) = 1 

다음은 상자를 작성하는 코드입니다.

DECLARE @geomenvelope GEOMETRY; 

DECLARE @BoundingBox AS TABLE 
    (
    SouthLat DECIMAL(10, 8) 
    ,NorthLat DECIMAL(10, 8) 
    ,EastLong DECIMAL(10, 8) 
    ,WestLong DECIMAL(10, 8) 
    ); 

SELECT @geomenvelope = GEOMETRY::STGeomFromWKB(zn.ZoneGeog.STAsBinary(), zn.ZoneGeog.STSrid).STEnvelope() 
    FROM dbo.GeogZone AS zn 
    WHERE zn.Zone = 'CA-1' 

INSERT INTO @BoundingBox (SouthLat,NorthLat,EastLong,WestLong) 
     SELECT @geomenvelope.STPointN(1).STY 
       ,@geomenvelope.STPointN(3).STY 
       ,@geomenvelope.STPointN(1).STX 
       ,@geomenvelope.STPointN(3).STX 

SELECT * 
    FROM @BoundingBox 

내 질문 : 내 지리 분야에서 East, West, North 및 South Point를 얻는 다른 방법이 있습니까?

답변

0

늦게 답변을 드려 죄송합니다.하지만 뭔가 추가 할 수 있기를 바랍니다. 그것은 단지 동일하게 작동하지만, 그렇게 쉽게 읽을 수 있어야하고 캐스트를 필요로하지 않습니다

GEOGRAPHY::Point(vlp.Lat, vlp.Long, 4326) AS LastKnownPoint 

다음과 같이

첫째, LastKnownPoint로 변환, 당신은 그것을 선언 할 수 있어야한다.

더 나은 성능을 얻으려면 Latitude/Long을 지형 열로 저장할 수 있으면 변환하지 않아도됩니다. 정기적으로 검색하는 경우 많은 오버 헤드가 발생합니다. 이렇게하면 구역을 필터로 직접 사용하고 공간 인덱스를 사용할 수있게되어 매우 권장 할 수 없게됩니다. 더 이상 경계 상자를 만들 필요가 없습니다.

모두 수행 할 수 없다면 적어도 CAST 및 연결 축소는 여기 저기에서 수천 밀리 초 정도 걸릴 것입니다.

+0

1. 나는 공간 지수를 사용합니다. 2. 경계 상자를 사용하거나 사용하지 않을 때 성능이 크게 달라 지므로 계속 사용하겠습니다. 3. 해당 테이블을 채우는 데 사용되는 현재 버전의 ETL 도구가이를 지원하지 않기 때문에 Geography Data 유형으로 저장할 수 없습니다. 4. 질문을 한 후 데이터가 자주 변경되지 않으므로 테이블에 내 경계 상자를 저장 했으므로 몇 달에 한 번만 빌드합니다. 나에게'GEOGRAPHY :: Point (vlp.Lat, vlp.Long, 4326) '를 사용하도록 코드를 바꿀 것이다. –

+0

@VladimirOselsky 어떤면에서 도움이 되었니 다행입니다. –