책너두 (Real MySQL 8.0 1권) 43일차 (~465p)

요약

  • Extra 칼럼의 나머지 값들을 이해하게 됨.
    • FirstMatch
    • Full scan on NULL key
    • Impossible HAVING
    • Impossible WHERE
    • LooseScan
    • No matching min/max row
    • no matching row in const table
    • No matching rows after partition pruning
    • No tables used
    • Not exists
      • 각 칼럼이 어느 상황에서 출력되는지 이해하게 됨.

메모

FirstMatch

  • 세미 조인의 여러 최적화 중, FirstMatch 전략이 사용되면 MySQL 옵티마이저는 실행 계획의 Extra 칼럼에 “FirstMatch(table_name)” 메시지를 출력함.
  • 9.3.1.11절 퍼스트 매치를 참조하자.

Full scan on NULL key

  • 이 처리는 “col1 IN (SELECT col2 FROM …)” 과 같은 조건을 가진 쿼리에서 자주 발생할 수 있음.
  • col1 값이 NULL이 된다면 결과적으로 조건은 “NULL IN (SELECT col2 FROM …)” 과 같이 바뀜.
  • SQL 표준에서 NULL을 “알 수 없는 값”으로 정의하고 있음.
    • NULL에 대한 연산의 규칙까지 정의하고 있음.
    • 그 정의대로 연산을 수행하기 위해 이 조건은 다음과 같이 비교돼야 함.
      • 서브쿼리가 1건이라도 결과 레코드를 가진다면 최종 비교 결과는 NULL
      • 서브쿼리가 1건도 결과 레코드를 가지지 않는다면 최종 비교 결과는 FALSE
        • 이 비교 과정에서, col1이 NULL 이면 사용된 테이블에 대해 풀 테이블 스캔을 해야만 결과를 알 수 있음.
        • Extra 칼럼의 “Full scan on NULL key”은 MySQL 서버가 쿼리를 실행하는 중, col1이 NULL을 만나면 차선책으로 서브쿼리 테이블에 대해 풀 테이블 스캔을 사용할 것이라는 사실을 알려주는 키워드임.
        • col1이 NOT NULL로 정의된 칼럼이라면 이러한 차선책은 사용되지 않고, Extra 칼럼에도 표시되지 않음.
  • 이 실행 계획이 Extra 칼럼에 표시됐다고 하더라도 IN 이나 NOT IN 연산자의 왼쪽에 있는 값이 실제로 NULL 이 없다면 풀 테이블 스캔은 발생하지 않으므로 걱정하지 않아도 됨.
    • 하지만 IN 이나 NOT IN 연산자의 왼쪽 값이 NULL인 레코드가 있고, 서브쿼리에 개별적으로 WHERE 조건이 지정돼 있다면 상당한 성능 문제가 발생할 수도 있음.

Impossible HAVING

  • 쿼리에 사용된 HAVING 절의 조건을 만족하는 레코드가 없을 때, 실행 계획의 Extra 칼럼에는 “Impossible HAVING” 키워드가 표시됨.
    • 이 실행 계획이 출력된다면 쿼리가 제대로 작성되지 못한 경우이므로 쿼리 내용을 다시 점검해야 함.

Impossible WHERE

  • “Impossible HAVING”과 비슷하며, WHERE 조건이 항상 FALSE가 될 수밖에 없는 경우 “Impossible WHERE”가 표시됨.

LooseScan

  • 세미 조인 최적화 중, LooseScan 최적화 전략이 사용되면 실행 계획의 Extra 칼럼에 “LooseScan” 문구가 표시됨.
  • 9.3.1.12 루스 스캔을 참조하자.

No matching min/max row

  • 쿼리의 WHERE 조건절을 만족하는 레코드가 한 건ㄷ ㅗ없는 경우 일반적으로 “Impossible WHERE…” 문장이 Extra 칼럼에 표시됨.
  • MIN(), MAX() 같은 집합 함수가 있는 쿼리의 조건절에 일치하는 레코드가 한 건도 없을 때, Extra 칼럼에 “No matching min/max row” 라는 메시지가 출력됨.

no matching row in const table

  • 조인에 사용된 테이블에서 const 방법으로 접근할 때 일치하는 레코드가 없다면 “no matching row in const table” 이라는 메시지를 표시함.
    • 실행 계획을 만들기 위한 기초 자료가 없음을 의미함.

No matching rows after partition pruning

  • 이 메시지는 파티션된 테이블에 대한 UPDATE 또는 DELETE 명령의 실행 계획에서 표시될 수 있음.
  • 해당 파티션에서 UPDATE 하거나 DELETE 할 대상 레코드가 없을 때 표시됨.
    • 단순히 삭제할 레코드가 없음을 의미하는게 아니라 대상 파티션이 없다는 것을 의미함.
    • 실제 삭제할 레코드는 없지만, 대상 파티션은 있는 경우라면 실행 계획에서 partitions 칼럼은 비어있지 않고, Extra 칼럼에도 위 메시지는 표시되지 않음.

No tables used

  • FROM 절이 없는 쿼리 문장이나 “FROM DUAL” 형태의 쿼리 실행 계획에서는 Extra 칼럼에 위 메시지가 표시됨
  • 다른 DBMS 와 달리 MySQL 서버는 FROM 절이 없는 쿼리도 허용함.
    • 이처럼 FROM 절 자체가 없거나 FROM 절에 상수 테이블을 의미하는 DUAL (칼럼과 레코드를 각각 1개씩만 가지는 가상의 상수 테이블)이 사용될 때는 “No tables used” 라는 메시지가 표시됨.

Not exists

  • 프로그램 개발하다 보면 A 테이블는 존재하지만 B 테이블에는 없는 값을 조회해야 하는 쿼리가 자주 사용됨.
  • 이럴 때 주로 NOT IN(subquery) 형태나 NOT EXISTS 연산자를 주로 사용함.
    • 이런 형태의 조인을 안티-조인(Anti-JOIN)이라고 함.
    • 똑같은 처리를 아우터 조인(LEFT OUTER JOIN)을 이용해서 구현할 수도 있음.
    • 일반적으로 NOT IN(subquery) 나 NOT EXISTS 등의 연산자를 사용하는 안티-조인으로 처리해야 하지만, 레코드 건수가 많을 땐 아우터 조인을 이용하면 빠른 성능을 낼 수 있음.
    • 아우터 조인(LEFT JOIN)과 WHERE 절에 조인 대상 칼럼이 NULL 인 레코드만 체크해서 가져오는 식으로 안티-조인을 구현한다.
      • 즉, 안티-조인은 일반 조인(INNER JOIN)을 했을 때 나오지 않는 결과만 가져오는 방법임.

댓글

Designed by JB FACTORY