MySQL的SQL_CALC_FOUND_ROWS真的很慢么?

作者: 老王  來源: 老王的技術手冊  發布時間: 2010-12-05 16:57  閱讀: 14427 次  推薦: 1   原文鏈接   [收藏]  

  分頁程序一般由兩條SQL組成:

 
SELECT COUNT(*) FROM ... WHERE ....
SELECT ... FROM ... WHERE LIMIT ...

  如果使用SQL_CALC_FOUND_ROWS的話,一條SQL就可以了:

 
SELECT SQL_CALC_FOUND_ROWS ... FROM ... WHERE LIMIT ...

  在得到數據后,通過FOUND_ROWS()可以得到不帶LIMIT的結果數:

 
SELECT FOUND_ROWS()

  看上去,似乎SQL_CALC_FOUND_ROWS應該快于COUNT(*),但實際情況并不是這樣簡單,請看:

  To SQL_CALC_FOUND_ROWS or not to SQL_CALC_FOUND_ROWS?

  用數據說話,證明了COUNT(*)相對SQL_CALC_FOUND_ROWS來說更快。不過我覺得這個結論也不全面,某些情況下,SQL_CALC_FOUND_ROWS更有優勢,看我的實驗:

  表結構如下:

 
CREATE TABLE IF NOT EXISTS `foo` (
`a`
int(10) unsigned NOT NULL AUTO_INCREMENT,
`b`
int(10) unsigned NOT NULL,
`c`
varchar(100) NOT NULL,
PRIMARY KEY (`a`),
KEY `bar` (`b`,`a`)
) ENGINE
=MyISAM;

  導入一些測試數據:

 
for ($i = 0; $i <10000; $i++) {
mysql_query(
"INSERT INTO foo SET b=ROUND(RAND()*10), c=MD5({$i})");
}

  先測試COUNT(*)方式:

 
$start = microtime(true);
for ($i = 0; $i < 1000; $i++) {
mysql_query(
"SELECT SQL_NO_CACHE COUNT(*) FROM foo WHERE b = 1");
mysql_query(
"SELECT SQL_NO_CACHE a FROM foo WHERE b = 1 LIMIT 100, 10");
}
$end
= microtime(true);
echo $end
- $start;

  結果輸出(數據大小視測試機性能而定):0.75777006149292

  再測試SQL_CALC_FOUND_ROWS方式:

 
$start = microtime(true);
for ($i = 0; $i < 1000; $i++) {
mysql_query(
"SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS a FROM foo WHERE b = 1 LIMIT 100, 10");
mysql_query(
"SELECT FOUND_ROWS()");
}
$end
= microtime(true);
echo $end
- $start;

  結果輸出(數據大小視測試機性能而定):0.6681969165802

  有數據有真相,那為什么我的實驗結論和MySQL Performance Blog的結論相悖呢?這是因為在MySQL Performance Blog的實驗里,COUNT(*)查詢是執行的的Covering Index,而SQL_CALC_FOUND_ROWS是執行的表查詢;而在我的實驗里,因為我定義了適當的索引,COUNT(*)和SQL_CALC_FOUND_ROWS都是執行的Covering Index,所以結論出現了差異。

  既然使用了Covering Index,就意味著不能再使用SELECT *的形式了,只能使用類似SELECT id這樣的形式了,用的列在索引里都能查到,如此說來,我們需要的實際數據從哪來呢?這個很簡單,有了主鍵之后,實際數據可以通過Key/Value形式的緩存獲得,這樣的架構很常見。

  結論:SQL_CALC_FOUND_ROWS如果執行的是Covering Index的話,是很快的!換個角度看,如果COUNT(*)和SQL_CALC_FOUND_ROWS都只能通過表查詢來檢索,那么分頁時,SQL_CALC_FOUND_ROWS同樣會快于COUNT(*),讀者可自行測試。

1
0
 
標簽:MySQL
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()