Explain이 답을 알 때 count (*)가 느린 이유는 무엇입니까?


14

이 쿼리 : select count(*) from planner_event실행하는 데 시간이 오래 걸립니다. 너무 오래 걸리기 전에 포기하고 죽였습니다. 그러나을 실행 explain select count(*) from planner_event하면 행 수 (14m)가있는 출력에서 ​​열을 볼 수 있습니다.

어떻게 설명하면 행 수를 즉시 얻을 수 있지만 count (*)를 실행하는 데 시간이 오래 걸립니까?


WHERE 원인이없는 COUNT (*)는 InnoDB 엔진에서 테이블을 스캔합니다. MyCOUNT는 COUNT가 헤더 파일에 테이블에서 유지되므로 카운트를 직접 전달할 수 있습니다.
Raymond Nijland

답변:


16

Explain이 이전에 수집 한 통계를 사용하고 있습니다 (쿼리 옵티마이 저가 사용). 이렇게하면 select count(*)매주 데이터 블록을 읽습니다.

예상 행 수를 얻는 가장 저렴한 방법은 다음과 같습니다.

select TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME='planner_event';

당신이 한 경우에도 select count(id)당신이 보조 인덱스가 없다면, 그것은 여전히 매우 긴 시간이 걸릴 수 있습니다 id(또한 가정을 id기본 키입니다). 모든 데이터 (행 데이터 포함)가 B- 트리 인덱스에 저장되므로 a를 수행하는 select count(PK_COLUMN)것은 여전히 ​​상당한 양의 IO입니다 (모든 데이터 페이지를 읽어야 함). PK 필드에 보조 인덱스가있는 경우 카운트를 수행하기 위해 더 적은 IO를 수행 할 수 있습니다.


I_S.TABLES는 동일한 추정치EXPLAIN제공합니다.
Rick James

쿼리가 누락되었습니다 AND TABLE_SCHEMA='my_database'. 그렇지 않으면 다른 데이터베이스에 이름이 같은 테이블이 있으면 여러 개의 결과가 다시 나타납니다.
cz

3

Explain은 옵티마이 저의 항목을 추정하는 데 사용되는 일부 "통계"에서 숫자를 얻습니다. 이 숫자는 정확하지 않을 수 있습니다. 때로는 정확한 값보다 2 배 이상 (높거나 낮음) 인 것으로 보입니다.

COUNT(*)InnoDB 테이블에서 수행하면 다른 연결에 의해 삽입 / 삭제 중이지만 아직 "커밋되지 않은"잘못된 카운트 레코드를 피하기 위해 테이블을 스캔해야합니다. 실제로, 전체 테이블 (을 포함하는 PRIMARY KEY) 은 아니지만 일부 인덱스에서 전체 스캔을 수행하는 것이 좋습니다 .

당신은 얼마나 많은 RAM을 가지고 있습니까? 의 가치는 innodb_buffer_pool_size무엇입니까? RAM의 약 70 %라면 도움이 될 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.