수색…


통사론

  • 동일한 SELECT에서 DISTINCT와 GROUP BY를 사용하지 마십시오.

  • OFFSET을 통해 페이지 매김을하지 마십시오. "중단 한 부분을 기억하십시오."

  • WHERE (a, b) = (22,33)은 전혀 최적화되지 않습니다.

  • UNION 뒤에 ALL 또는 DISTINCT를 명시 적으로 말하면 - 더 빠 른 ALL 또는 느린 DISTINCT 중에서 선택하십시오.

  • SELECT *를 사용하지 마십시오. 특히 필요하지 않은 TEXT 또는 BLOB 열이있는 경우. tmp 테이블과 전송에 오버 헤드가 있습니다.

  • GROUP BY와 ORDER BY가 정확히 같은 목록을 가질 수있을 때 더 빠릅니다.

  • FORCE INDEX를 사용하지 마십시오. 그것은 오늘 도움이 될지 모르지만, 아마 내일 다치게 할 것입니다.

비고

ORDER BY, LIKE, REGEXP 등에 관한 토론을 참조하십시오. 참고 : 링크 및 기타 주제로 편집해야합니다.

최적의 지표를 구축하기위한 요리 책 .

올바른 색인 추가

이것은 거대한 주제이지만, 가장 중요한 "성과"문제이기도합니다.

초보자를위한 주된 교훈은 "복합"색인을 배우는 것입니다. 다음은 간단한 예입니다.

INDEX(last_name, first_name)

다음과 같이 우수합니다.

WHERE last_name = '...'
WHERE first_name = '...' AND last_name = '...'   -- (order in WHERE does not matter)

그러나를 위해 아닙니다

WHERE first_name = '...'   -- order in INDEX _does_ matter
WHERE last_name = '...' OR first_name = '...'   -- "OR" is a killer

캐시를 올바르게 설정하십시오.

innodb_buffer_pool_size 는 사용 가능한 RAM의 약 70 % 여야합니다.

비효율적 인 구조는 피하십시오.

x IN ( SELECT ... )

JOIN 으로 변신하다

가능한 경우 OR 피하십시오.

WHERE DATE(x) = ... 와 같은 함수에서 인덱스 된 열을 '숨기지 마십시오.'; WHERE x = ... 로 재 공식화 WHERE x = ...

일반적으로 적합한 데이터 정렬을 사용하여 WHERE LCASE(name1) = LCASE(name2) 를 피할 수 있습니다.

"페이지 설정"에 OFFSET 을 사용하지 말고 대신 '중단 한 부분을 기억하십시오'.

SELECT * ... 피하십시오 (디버깅하지 않는 한).

Maria Deleva, Barranka, Batsu에 대한 참고 사항 : 이것은 장소 소유자입니다. 전체 예제를 빌드 할 때 이러한 항목을 제거하십시오. 당신이 할 수있는 것들을 해본 후에 나는 나머지 부분을 정교하게 그리고 / 또는 던질 것입니다.

제외 어

다음은 실적 향상에 도움이되지 않는 몇 가지 사항입니다. 오래된 정보 및 / 또는 순진함에서 비롯된 것입니다.

  • InnoDB는 MyISAM이 더 좋을 것 같지 않은 지점으로 개선되었습니다.
  • PARTITIONing 은 성능상의 이점을 거의 제공하지 않습니다. 그것은 심지어 성능을 해칠 수 있습니다.
  • 설정 query_cache_size 보다 큰 1 억 것은 일반적으로 성능이 저하됩니다.
  • my.cnf 에서 값을 많이 늘리면 '스와핑'이 발생할 수 있습니다. 이는 심각한 성능 문제입니다.
  • "접두어 인덱스"(예 : INDEX(foo(20)) )는 일반적으로 쓸모가 없습니다.
  • OPTIMIZE TABLE 은 거의 쓸모가 없습니다. (그리고 그것은 테이블을 잠그는 것을 포함한다.)

색인 있음

작은 테이블이 아닌 쿼리의 속도를 높이는 가장 중요한 방법은 적절한 인덱스를 만드는 것입니다.

WHERE a = 12  --> INDEX(a)
WHERE a > 12  --> INDEX(a)

WHERE a = 12 AND b > 78  --> INDEX(a,b) is more useful than INDEX(b,a)
WHERE a > 12 AND b > 78  --> INDEX(a) or INDEX(b); no way to handle both ranges

ORDER BY x  --> INDEX(x)
ORDER BY x, y  --> INDEX(x,y) in that order
ORDER BY x DESC, y ASC  --> No index helps - because of mixing ASC and DESC

기능을 숨기지 마십시오.

일반적인 실수는 함수 호출 내에서 인덱싱 된 열을 숨기는 것입니다. 예를 들어, 이것은 인덱스에서 도움을받을 수 없습니다.

WHERE DATE(dt) = '2000-01-01'

대신 INDEX(dt) 주어지면 INDEX(dt) 사용할 수 있습니다.

WHERE dt = '2000-01-01'  -- if `dt` is datatype `DATE`

이것은 DATE , DATETIME , TIMESTAMP 및 심지어 DATETIME(6) (마이크로 초) 동안 작동합니다.

WHERE dt >= '2000-01-01'
  AND dt  < '2000-01-01' + INTERVAL 1 DAY

또는

일반적으로 OR 최적화를 죽입니다.

WHERE a = 12 OR b = 78

INDEX(a,b) 사용할 수 없으며 "인덱스 병합"을 통해 INDEX(a), INDEX(b) 를 사용하거나 사용하지 않을 수 있습니다. 인덱스 병합은 아무 것도없는 것보다 낫지 만 간신히.

WHERE x = 3 OR x = 5

로 바뀌다

WHERE x IN (3, 5)

그 안에 x 가있는 색인을 사용할 있습니다.

하위 쿼리

하위 쿼리는 여러 가지 형식으로 제공되며 최적화 가능성이 다릅니다. 먼저, 하위 쿼리는 "상관 관계"또는 "상관 관계 없음"중 하나 일 수 있습니다. 상관 관계 란 서브 쿼리 외부의 값에 의존한다는 의미입니다. 이것은 일반적으로 각 외부 값에 대해 하위 쿼리 다시 평가 해야 함을 의미합니다.

이 상관 관계가있는 부질의는 종종 꽤 좋다. 참고 : 최대 1 개의 값을 반환해야합니다. LEFT JOIN 보다는 반드시 빠르지는 않지만 대체로 유용합니다.

SELECT a, b, ( SELECT ... FROM t WHERE t.x = u.x ) AS c
    FROM u ...
SELECT a, b, ( SELECT MAX(x) ... ) AS c
    FROM u ...
SELECT a, b, ( SELECT x FROM t ORDER BY ... LIMIT 1 ) AS c
    FROM u ...

이것은 일반적으로 상관 관계가 없습니다.

SELECT ...
    FROM ( SELECT ... ) AS a
    JOIN b ON ...

FROM-SELECT 에 관한주의 사항 :

  • 1 행을 반환하면 좋습니다.
  • 좋은 패러다임 (다시 "1 row")은 하위 쿼리가 ( SELECT @n := 0 ) , 나머지 변수 나 쿼리에서 사용할 @variable을 초기화하는 것입니다.
  • 그것은 많은 행을 반환하고이 경우 JOIN( SELECT ... ) 많은 행이 다음 효율성은 끔찍한 될 수 있습니다. 5.6 이전에는 색인이 없었기 때문에 CROSS JOIN 이되었습니다. 5.6+는 임시 테이블에서 최상의 인덱스를 추론 한 다음 생성하여 SELECT 끝내면 버립니다.

JOIN + GROUP BY

비효율적 인 쿼리로 이어지는 일반적인 문제는 다음과 같이됩니다.

SELECT ...
    FROM a
    JOIN b  ON ...
    WHERE ...
    GROUP BY a.id

먼저 JOIN 은 행 수를 확장합니다. GROUP BY 그것을 a 의 행 수만큼 되 돌린다.

이 폭발 - 함몰 문제를 해결하기위한 좋은 선택은 없을 것입니다. 한 가지 가능한 옵션은 JOINSELECT 의 상관 된 하위 쿼리로 변환하는 것입니다. 이것은 또한 GROUP BY 제거합니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow