天天看點

[InnoDB系列] -- innodb表如何更快得到count(*)結果

作/譯者:葉金榮(Email:

[InnoDB系列] -- innodb表如何更快得到count(*)結果

),來源:http://imysql.cn,轉載請注明作/譯者和出處,并且不能用于商業用途,違者必究。

起因:在innodb表上做count(*)統計實在是太慢了,是以想辦法看能不能再快點。

現象:先來看幾個測試案例,如下

一、 sbtest 表上的測試

填充了 1000萬條 記錄。

1、 直接 count(*)

可以看到,如果不加任何條件,那麼優化器優先采用 primary key 來進行掃描。

2、count(*) 使用 primary key 字段做條件

可以看到,盡管優化器認為隻需要掃描 485600 條記錄(其實是索引),比剛才少多了,但其實仍然要做全表(索引)掃描。是以耗時和第一種相當。

3、 count(*) 使用 secondary index 字段做條件

可以看到,采用這種方式查詢會非常快。

有人也許會問了,會不會是因為 id 字段的長度比 aid 字段的長度來的小,導緻它掃描起來比較快呢?先不着急下結論,咱們來看看下面的測試例子。

二、 sbtest1 表上的測試

這個表裡,把 aid 和 id 的字段長度調換了一下,也填充了 1000萬條 記錄。

上面的所有測試,均在 mysql 5.1.24 環境下通過,并且每次查詢前都重新開機了 mysqld。

可以看到,把 aid 和 id 的長度調換之後,采用 secondary index 查詢仍然是要比用 primary key 查詢來的快很多。看來主要不是字段長度引起的索引掃描快慢,而是采用 primary key 以及 secondary index 引起的差別。那麼,為什麼用 secondary index 掃描反而比 primary key 掃描來的要快呢?我們就需要了解innodb的 clustered index 和 secondary index 之間的差別了。

innodb 的 clustered index 是把 primary key 以及 row data 儲存在一起的,而 secondary index 則是單獨存放,然後有個指針指向 primary key。是以,需要進行 count(*) 統計表記錄總數時,利用 secondary index 掃描起來,顯然更快。而primary key則主要在掃描索引,同時要傳回結果記錄時的作用較大,例如:

那既然是使用 secondary index 會比 primary key 更快,為何優化器卻優先選擇 primary key 來掃描呢,<b>Heikki Tuuri</b> 的回答是:

詳情請看:這個 bug,以及這個文章:InnoDB Row Counting using Indexes。

最後感謝老楊的幫助。

本文出自 “MySQL中文網”部落格 http://www.imysql.cn/

繼續閱讀