国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > SQL Server > 正文

SQL_CALC_FOUND_ROWS真的很慢么?

2024-08-31 00:43:44
字體:
來源:轉載
供稿:網友

分頁程序一般由兩條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(*),讀者可自行測試。

補充:Fast paging in the real world

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 肥西县| 安溪县| 扎赉特旗| 平舆县| 三明市| 公安县| 勃利县| 乌什县| 县级市| 华阴市| 景东| 湟源县| 读书| 永昌县| 策勒县| 山阳县| 噶尔县| 苍梧县| 嘉荫县| 宜宾县| 晋宁县| 怀远县| 贵阳市| 沁水县| 潮安县| 大厂| 泰兴市| 德保县| 施甸县| 璧山县| 高要市| 武汉市| 东台市| 穆棱市| 贺兰县| 巩义市| 湾仔区| 白城市| 宜兰县| 灌南县| 虞城县|