이 쿼리 : select count(*) from planner_event
실행하는 데 시간이 오래 걸립니다. 너무 오래 걸리기 전에 포기하고 죽였습니다. 그러나을 실행 explain select count(*) from planner_event
하면 행 수 (14m)가있는 출력에서 열을 볼 수 있습니다.
어떻게 설명하면 행 수를 즉시 얻을 수 있지만 count (*)를 실행하는 데 시간이 오래 걸립니까?
이 쿼리 : select count(*) from planner_event
실행하는 데 시간이 오래 걸립니다. 너무 오래 걸리기 전에 포기하고 죽였습니다. 그러나을 실행 explain select count(*) from planner_event
하면 행 수 (14m)가있는 출력에서 열을 볼 수 있습니다.
어떻게 설명하면 행 수를 즉시 얻을 수 있지만 count (*)를 실행하는 데 시간이 오래 걸립니까?
답변:
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를 수행 할 수 있습니다.
EXPLAIN
제공합니다.
AND TABLE_SCHEMA='my_database'
. 그렇지 않으면 다른 데이터베이스에 이름이 같은 테이블이 있으면 여러 개의 결과가 다시 나타납니다.
Explain은 옵티마이 저의 항목을 추정하는 데 사용되는 일부 "통계"에서 숫자를 얻습니다. 이 숫자는 정확하지 않을 수 있습니다. 때로는 정확한 값보다 2 배 이상 (높거나 낮음) 인 것으로 보입니다.
COUNT(*)
InnoDB 테이블에서 수행하면 다른 연결에 의해 삽입 / 삭제 중이지만 아직 "커밋되지 않은"잘못된 카운트 레코드를 피하기 위해 테이블을 스캔해야합니다. 실제로, 전체 테이블 (을 포함하는 PRIMARY KEY
) 은 아니지만 일부 인덱스에서 전체 스캔을 수행하는 것이 좋습니다 .
당신은 얼마나 많은 RAM을 가지고 있습니까? 의 가치는 innodb_buffer_pool_size
무엇입니까? RAM의 약 70 %라면 도움이 될 것입니다.