2017-09-08 1 views
1

SQL 쿼리를 실행하여 특정 위치가 다각형으로 정의 된 관할 구역에 속하는지 확인해야하는 응용 프로그램을 작성 중입니다. 이러한 관할 구역은 분기별로 업데이트되므로, 내가 확인하고있는 날짜와 비교하여 확인해야합니다. 나는이라는 mySQL 함수를 사용하여 내가보고있는 관할권의 범위를 좁히고, 내 응용 프로그램이 주어진 지점이 어느 지점에 있는지 쉽게 확인하도록합니다.평가 순서를 변경하여 SQL 쿼리의 실행 시간 단축

SELECT DISTINCT t0.id FROM jurisdiction t0 
WHERE t0.beginDate <= '2017-08-05' AND t0.endDate >= '2017-08-05' 
AND MBRContains(t0.geometry,GeomFromText("POINT(48.0 -120.0)")); 

내가 MBRContains 날짜를 확인보다 더 비용이 많이 드는 작업임을 매우 확신 해요,하지만 난 많은 SQL로 근무 한 적이없는 내가하는 방법을 확실 해요 : 바로 지금, 내 쿼리는 다음과 같이 관할권이 먼저 날짜별로 필터링되고 MBRContains에 대해 확인됩니다. 어떻게해야합니까? 이 쿼리로 동일한 결과를 얻는 동안 수행 할 수있는 다른 최적화가 있습니까?

+0

오타 인 지 확실하지 않지만 잘못된 날짜입니다. 하나의 날짜 필드는'DATE' 데이터 타입이어야합니다; 다른 경우에는 문자열 값을 사용하는 경우에도 해당 비교가 실제로 의미가있는 방식으로 문자열을 형식화해야합니다 ('06 -08-2001 '의 종료 날짜는 '05 -08-2017'다음으로 끝남). 마찬가지로 '04 -08-2020 '의 시작 날짜는 '05 -08-2017'이전입니다.) – Uueerdo

+0

@Uueerdo 날짜와 요요는 예제입니다. 나는 그것이 올바른 날짜에 전달되고 결과를 올바르게 필터링하고 있음을 확인했습니다. 쿼리가 너무 오래 걸리는 것입니다. – user3726962

+0

beginDate, endDate 및 geometry에 인덱스를 사용하면 액세스 속도가 빨라집니다. – hackela

답변

2

(beginDate, endDate)에 색인을 추가합니다. 두 필드 모두에서 하나의 인덱스가 별도의 인덱스가 아닙니다.

또한 제공된 날짜가 항상 단일 날짜 인 경우 조건의 날짜 부분을 '2017-08-05' BETWEEN t0.beginDate AND t0.endDate일 수 있습니다.은 더 도움이됩니다 (그러나 그렇지 않을 수도 있음).

또한 이전에 비슷한 질문을했는데 인덱스에서 이점을 얻을 수있는 간단한 경계 검사와 함께 추가 조건을 사용하는 것이 좋습니다. 그러나 일반적으로 더 큰 경계 상자가 사용될 수있는 상황을 포함합니다. 의사 조건은 "경계 상자에서 및 경계 영역에서"와 같을 것입니다. "바운딩 박스에서"인덱스를 사용하여 멀리있는 점을 제거하고 더 복잡한 "경계 영역"에 대해 점검되는 점의 수를 줄입니다.

1

MBRContainsGeomFromText 인 경우 결정적 기능이며 플래그 지정되지 않으면 도움이 될 수 있습니다.

결정 성 함수는 항상 동일한 입력으로 동일한 값을 반환하는 함수입니다. UPPER()는 항상 동일한 입력에 대해 동일한 출력을 제공하기 때문에 결정적입니다. 이는 중간 값이 절대로 변경되지 않는다는 것을 안다면 옵티마이 저가 바로 가기를 만들 수 있음을 의미합니다.

(지금은 주위를 검색 할 것을, 나는 그 기능은 데이터베이스의 일부로 제공되는 참조하지 것들을 당신에게 다음에 대한 추가 결정 함수의

썼다, 그래서 당신은 그들을 제어 할 수 없을 것이다. 아직도 함수를 호출하는 SQL의 속도를 높일 수있는 방법의 예로서 대답을 남긴다.)

+0

아니요. 'DATE (col)'은 결정적이지만 최적화 프로그램은 WHERE DATE (col) = CURDATE()에 대해 INDEX (col)을 사용하지 않습니다. 다른 바로 가기도 없습니다. 그것은 펀트. (OK,'CURDATE'는 한 번만 평가할 것입니다.) –

1

당신이하는 것처럼 범위를 확인하는 것은 잘 최적화되지 않는 것입니다. 당신이 얻을 수있는 최선은 테이블 절반을 스캔하는 것입니다. 그리고 그것은 문제가됩니다.

효과적으로 스캔을해야합니다. 그런 다음 WHERE의 어느 부분이 먼저 평가 될 것인지에 대한 질문은 사소한 것으로 판명됩니다. 이는 행을 가져 오는 것이 WHERE 절에있을 수있는 거의 모든 함수보다 훨씬 비쌉니다.

geometrySPATIAL 색인을 사용해 보셨습니까? 일 수도 있고 일 수 있습니다. 그렇다면이 답변의 나머지 부분은 문제가됩니다.당신이 큰 데이터 세트에 대해 얘기하는 경우,

WHERE x BETWEEN ... 
    AND y BETWEEN ... 

INDEX(x), 
INDEX(y) 

가 (아니, INDEX(x,y)이 더 나은 작동하지 않습니다.)

: 이미 언급

로서, "경계 상자"좋은 첫 시도 more complex solution이 필요할 수 있습니다.