복붙노트

[SQL] A의 필드의 순서는 WHERE 절 MySQL의 성능에 영향을 미칩니 까?

SQL

A의 필드의 순서는 WHERE 절 MySQL의 성능에 영향을 미칩니 까?

유형 및 사용자 ID (개별 인덱스가 아닌 복합) - 나는 테이블에서 두 개의 인덱스 필드가 있습니다.

유형 필드 값은 매우 그래서 테이블 레코드의 50 %가 같은 유형이, (하자가 만 0 또는 1 말) 제한됩니다. 동일한 사용자 ID 레코드의 양이 작도록 아이디 값은, 다른 한편으로는, 더 큰 세트로부터 온다.

이러한 쿼리의 다른 하나보다 더 빠르게 실행됩니다 :

select * from table where type=1 and userid=5
select * from table where userid=5 and type=1

두 필드가 인덱싱되지 않은 경우 또한, 동작을 변경할 것인가?

해결법

  1. ==============================

    1.SQL은 선언적 언어가 아닌 절차 하나가 될 수 있도록 설계되었습니다. 따라서 쿼리 최적화 프로그램을 적용하는 방법을 결정하는 where 절 술어의 순서를 고려하지합니다.

    SQL은 선언적 언어가 아닌 절차 하나가 될 수 있도록 설계되었습니다. 따라서 쿼리 최적화 프로그램을 적용하는 방법을 결정하는 where 절 술어의 순서를 고려하지합니다.

    나는 아마 SQL 쿼리 최적화의 다음 설명을 과도하게 단순화 waaaay를하겠습니다. 나는이 선 (재미의 톤!) 함께 일년 전에 썼다. 당신이 정말로 현대 쿼리 최적화 파고 싶은 경우에, 오라일리에서 댄 견인의 SQL 튜닝을 참조하십시오.

    간단한 SQL 쿼리 최적화 프로그램에서 SQL 문을 처음으로 관계 대수 연산의 나무로 컴파일됩니다. 이들 동작 각각 인출 입력과 같은 하나 개 이상의 테이블은 출력으로서 다른 테이블을 생성한다. 스캔 된 순차 검색 데이터베이스에서 테이블을 읽습니다. 정렬 정렬 된 테이블을 생성합니다. 선택 행 그 일부 선택 조건에 따라 다른 테이블로부터 선택되는 테이블을 생성한다. 프로젝트는 다른 테이블의 특정 열이있는 테이블을 생성합니다. 크로스 제품은 행 생각할 수있는 모든 페어링으로 구성된 출력 테이블을 두 테이블을 받아 생산하고 있습니다.

    혼동의 SQL SELECT 절은 관계 대수 프로젝트로 컴파일하는 관계 대수 선택에 WHERE 절 회전하면서. 절 회전에서 하나 이상의 조인으로, 각각 두 개의 테이블을 복용하고 생산 한 테이블 밖으로. 이 합집합, 교집합, 차이 및 회원을 포함한 다른 관계 대수 연산이 있지만,하자이 간단한 유지.

    이 나무는 정말 최적화 될 필요가있다. 예를 들어, 당신은 할 경우 :

    select E.name, D.name 
    from Employee E, Department D 
    where E.id = 123456 and E.dept_id = D.dept_id
    

    맹목적으로 한 직원 한 부서 (크로스 제품)의 모든 가능한 조합을 제작 한 다음 필요했던 단지 하나 개의 조합을 선택 것이다 최적화되지 않은 나무를 실행 (500 개) 부서에서 5,000 명의 직원과 함께. 직원의 검사는 5,000 레코드 테이블을 생성 할 것이다, 부서의 검사는 500 기록 테이블, 2,500,000 레코드 테이블을 생성합니다 두 테이블의 크로스 제품을 생산하며, E.id의 선택이 걸릴 것이다 2,500,000 기록 테이블과 모든하지만 하나 싶었다 기록을 폐기합니다.

    [실제 쿼리 프로세서는 물론 메모리에이 중간 테이블을 모두 실현하지하려고합니다.]

    그래서 쿼리 최적화 트리를 산책하고 다양한 최적화를 적용한다. 하나는 선택의 체인, 원래의 선택의 최고 수준의 조건 각각에 대해 하나에 사람을 각 선택을 중단하는 것입니다 - 에드 함께. (이것은 "논리 곱 표준형"라고합니다.) 그런 다음 각각의 작은 선택이 나무의 주위에 이동하고보다 효율적으로 사람을 형성하기 위해 다른 관계형 대수 연산과 병합됩니다.

    위의 예에서, 최적화 알고리즘은 먼저 E.id에 선택 = 고가의 크로스 제품 작동 아래 123456 아래를 푸시합니다. 이 수단 십자가 제품은 500 행 (즉, 직원과 한 부서의 각 조합에 대해 하나)을 생성합니다. 그런 다음 E.dept_id = D.dept_id의 최상위 선택은 499 개 원치 않는 행을 필터링합니다. 나쁘지 않다.

    직원의 ID 필드에 인덱스가 있다면, 옵티마이 저는 빠른 인덱스 조회를 형성하기 위해 E.id = 123456의 선택과 직원의 검사를 결합 할 수 있습니다. 이 방법은 하나의 직원 행이 디스크 대신 5000에서 메모리로 읽어된다. 상황이 찾고있다.

    마지막 주요 최적화 E.dept_id = D.dept_id에 선택을하고 외적와 결합하는 것입니다. 이것은 관계 대수 동등 조인 작업으로 바뀝니다. 이것은 그 자체로 많은 일을하지 않습니다. Department.dept_id에 인덱스가 있다면, 그때 부서의 낮은 수준 순차적 스캔은 동등 조인은 우리의 한 직원의 부서 레코드의 매우 빠른 인덱스 조회로 전환 할 수 있습니다 먹이.

    약소 최적화 프로젝트 작업을 아래로 밀어 포함한다. 쿼리의 최상위 레벨 그냥 E.name 및 D.name을 필요로하고 조건이 E.id, E.dept_id 및 D.dept_id 필요한 경우, 다음 스캔 작업은 다른 모든과 중간 테이블을 구축 할 필요가 없습니다 열은 쿼리 실행시 공간을 절약. 우리는 두 개의 인덱스 조회에 끔찍하게 느린 쿼리를 설정하고별로 다른했습니다.

    원래의 질문으로 더 얻는 것은, 이제 당신이있어 가정 해 봅시다 :

    select E.name 
    from Employee E 
    where E.age > 21 and E.state = 'Delaware'
    

    최적화되지 않은 관계 대수 트리가 실행될 때, 쿼리 최적화 프로그램은 또한 데이터베이스에있는 값의 일부 거친 아이디어가 21보다 오래된 델라웨어에 5,000 명의 직원과 생산, 말, 126 사람에 스캔 것입니다. 그것은 E.state 열이 회사는 E.age 분포에 대한에 위치, 무언가를 가지고있는 14 개 주를 가지고 있음을 알 수 있습니다. 두 필드가 인덱싱한다면 먼저가 본다. E.state 인 경우는 쿼리 프로세서의 용의자가 마지막으로 계산 된 통계를 기반으로 델라웨어에있는 직원의 작은 번호를 선택하는 그 인덱스를 사용하는 의미가 있습니다. 단지 E.age 인 경우, 쿼리 프로세서 가능성이 전 직원의 96 %가 22 세 이상이기 때문에 그, 그럴 가치가 없어 것을 결정한다. E.state 인덱싱한다면, 우리의 쿼리 프로세서 나누기 선택과 병합 E.state은 = 스캔과 '델라웨어'는 훨씬 더 효율적 인덱스 스캔으로 전원을 켭니다.

    하자가 E.state 및 E.age에는 인덱스가 없음이 예에서 말한다. 결합 선택 작업은 순차적 직원의 "스캔"다음에 일어난다. 먼저 완료 선택의 조건이 달라 지나요? 아마 많은. 쿼리 프로세서는 SQL 문에 원래의 순서로 떠날 수도, 또는 예상 비용으로 좀 더 세련된 모습 일 수 있습니다. 통계에서, 다시는 조건을 반대로하고 첫 번째 할 것 있도록 E.state이 = '델라웨어'상태가 너무, 만 126 E.age>보다 매우 선택적해야 찾을 것 (21 개) 비교 대신 5000 . 아니면 문자열 평등 비교가 훨씬 더 비싼 정수 비교보다 것을 깨닫고 혼자 순서를두고 있습니다.

    어쨌든,이 모든 것이 매우 복잡하고 구문 조건 순서는 차이가 매우 어렵다. 당신이 진짜 성능 문제를 가지고 데이터베이스 공급 업체가 힌트로 상태 순서를 사용하지 않는 한 나는 그것에 대해 걱정하지 않을 것입니다.

  2. ==============================

    2.대부분의 쿼리 최적화는 조건이 힌트로 표시되는 순서를 사용합니다. 다른 모든 같은 경우, 그들은 그 순서를 따라야합니다.

    대부분의 쿼리 최적화는 조건이 힌트로 표시되는 순서를 사용합니다. 다른 모든 같은 경우, 그들은 그 순서를 따라야합니다.

    그러나 많은 일들이 그것을 대체 할 수 있습니다 :

    당신이 성능 문제를 관찰하지 않는 그래서하지 (상상) 성능을 위해, 명확성을 위해 최적화에 더 나은, (이 모든 SQL 최적화 문제도 마찬가지입니다).

  3. ==============================

    3.그것은 당신의 작은 예에서해야하지. 쿼리 최적화 프로그램은 옳은 일을해야한다. 당신은 쿼리의 전면에 설명 추가하여 확실히 확인할 수 있습니다. 그것은 함께 일을 가입하고 얼마나 많은 행이 조인을 수행하기 위해 검색 할 필요가 어떻게 MySQL은 당신을 말할 것이다. 예를 들면 :

    그것은 당신의 작은 예에서해야하지. 쿼리 최적화 프로그램은 옳은 일을해야한다. 당신은 쿼리의 전면에 설명 추가하여 확실히 확인할 수 있습니다. 그것은 함께 일을 가입하고 얼마나 많은 행이 조인을 수행하기 위해 검색 할 필요가 어떻게 MySQL은 당신을 말할 것이다. 예를 들면 :

    타입 1 사용자 ID = 5 = 테이블에서 선택을 설명 *

    그들이 색인되지 않은 경우 아마 동작을 변경합니다.

  4. from https://stackoverflow.com/questions/4035760/does-the-order-of-fields-in-a-where-clause-affect-performance-in-mysql by cc-by-sa and MIT license