SQL 문을 sargable로 만드는 것은 무엇입니까?
sargable은 정의에 의해 (적어도 내가 본 것에서) 쿼리 엔진이 쿼리가 사용하는 실행 계획을 최적화하도록 할 수 있음을 의미합니다. 나는 답을 찾으려고 노력했지만 주제에 대해서는별로없는 것 같습니다. 그렇다면 질문은 SQL 쿼리를 Sargable로 만들거나 만들지 않는 것입니다. 모든 문서는 대단히 감사하겠습니다.
참고 : SARGable
쿼리를 처리 불가능 하게 만드는 가장 일반적인 것은 where 절의 함수 내에 필드를 포함시키는 것입니다 .
SELECT ... FROM ...
WHERE Year(myDate) = 2008
SQL 옵티마이 저는 myDate에 인덱스가 존재하더라도이를 사용할 수 없습니다. 문자 그대로 테이블의 모든 행에 대해이 함수를 평가해야합니다. 사용하는 것이 훨씬 낫습니다.
WHERE myDate >= '01-01-2008' AND myDate < '01-01-2009'
다른 예 :
Bad: Select ... WHERE isNull(FullName,'Ed Jones') = 'Ed Jones'
Fixed: Select ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))
Bad: Select ... WHERE SUBSTRING(DealerName,4) = 'Ford'
Fixed: Select ... WHERE DealerName Like 'Ford%'
Bad: Select ... WHERE DateDiff(mm,OrderDate,GetDate()) >= 30
Fixed: Select ... WHERE OrderDate < DateAdd(mm,-30,GetDate())
이 작업을 수행하지 마십시오 :
WHERE Field LIKE '%blah%'
LIKE 값은 와일드 카드 문자로 시작하기 때문에 테이블 / 인덱스 스캔이 발생합니다.
이 작업을 수행하지 마십시오 :
WHERE FUNCTION(Field) = 'BLAH'
테이블 / 인덱스 스캔이 발생합니다.
데이터베이스 서버는 테이블의 모든 행에 대해 FUNCTION ()을 평가 한 후 'BLAH'와 비교해야합니다.
가능하면 반대로 수행하십시오.
WHERE Field = INVERSE_FUNCTION('BLAH')
이 매개 변수에 대해 INVERSE_FUNCTION ()을 한 번 실행하고 여전히 인덱스 사용을 허용합니다.
이 답변에서는 데이터베이스에 충분한 커버링 인덱스가 있다고 가정합니다. 이 주제 에 대해 충분한 질문 이 있습니다.
쿼리의 sargability는 많은 경우 관련 인덱스의 티핑 포인트에 의해 결정됩니다. 티핑 포인트는 한 테이블이나 결과 집합을 다른 테이블이나 조인하는 동안 인덱스 검색과 검색의 차이를 정의합니다. 한 번의 탐색은 전체 테이블을 스캔하는 것보다 훨씬 빠르지 만 많은 행을 탐색해야 할 때 스캔이 더 의미가 있습니다.
따라서 옵티마이 저가 한 테이블의 결과 행 수가 다음 테이블에서 가능한 인덱스의 팁 포인트보다 적을 것으로 예상 할 때 SQL 문을보다 잘 이해할 수 있습니다.
자세한 게시물과 예제는 여기에서 찾을 수 있습니다 .
작업을 sargable로 간주하려면 기존 인덱스를 사용하는 것만으로는 충분하지 않습니다. 위의 예에서 where 절의 색인화 된 열에 대해 함수 호출을 추가하면 정의 된 색인을 활용할 가능성이 높습니다. 해당 열 (인덱스)에서 모든 값을 "스캔"한 다음 제공된 필터 값과 일치하지 않는 값을 제거합니다. 행 수가 많은 테이블에는 여전히 효율적이지 않습니다. sargability를 실제로 정의하는 것은 정렬 된 항목 배열에 대한 반 집합 제거에 의존하는 이진 검색 방법을 사용하여 b-tree 인덱스를 순회하는 쿼리 기능입니다. SQL에서는 실행 계획에 "인덱스 찾기"로 표시됩니다.
참고 URL : https://stackoverflow.com/questions/799584/what-makes-a-sql-statement-sargable
'IT story' 카테고리의 다른 글
모든 http : // 링크를 // //로 변경할 수 있습니까? (0) | 2020.04.11 |
---|---|
Mercurial에서 기능 분기를 올바르게 닫는 방법은 무엇입니까? (0) | 2020.04.11 |
좋은 Java 그래프 알고리즘 라이브러리? (0) | 2020.04.11 |
변수를 소싱하지 않고 bash 스크립트에서 환경으로 변수를 내보낼 수 있습니까? (0) | 2020.04.11 |
Node.js가 단일 스레드 인 이유는 무엇입니까? (0) | 2020.04.11 |