하지만 물론 이러한 기능은 옵티마이저가 COUNT 쿼리를 날릴 때 cluster index까지 조회하지 않는다는 가정 하에 만족할 것이다.
실제로 그렇게 동작하는지 MySQL 공식 홈페이지를 방문해서 찾아보았으나, 어떻게 동작하는지는 자세히 나와있지 않고, 다음과 같은 글만 찾을 수 있었다.
InnoDBprocessesSELECT COUNT(*)statements by traversing the smallest available secondary index unless an index or optimizer hint directs the optimizer to use a different index. If a secondary index is not present,InnoDBprocessesSELECT COUNT(*)statements by scanning the clustered index.
ProcessingSELECT COUNT(*)statements takes some time if index records are not entirely in the buffer pool. For a faster count, create a counter table and let your application update it according to the inserts and deletes it does. However, this method may not scale well in situations where thousands of concurrent transactions are initiating updates to the same counter table. If an approximate row count is sufficient, useSHOW TABLE STATUS.
요약해 보자면, InnoDB는 보조 인덱스가 없으면cluster index를 모두 읽는데, 버퍼 풀에 인덱스 레코드가 없으면 느릴 수 있다는 것이다.
여기서 "데이터 레코드"가 아닌 "인덱스 레코드"를 언급한다는 점에서 내 생각과 꽤 비슷하게 동작하지 않을까 단순 추측하고 있다.
여기서 이런 생각을 해볼 수도 있을 것이다. 아니 row 수를 metadata 영역에 캐시하면 직접 데이터를 읽어서 해결할 수 있지 않나? 왜 굳이 데이터를 직접 읽어야 할까?
다음 글을 읽어보면 실제로도 MyISAM은 그러한 방법으로 동작하는 것 같다. 따라서 InnoDB보다 COUNT 쿼리의 성능이 훨씬 빠르다.