天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

Mysql中分頁查詢的兩個解決方法比較

mysql中分頁查詢有兩種方式, 一種是使用COUNT(*)的方式,具體代碼如下
復制代碼 代碼如下:
SELECT COUNT(*) FROM foo WHERE b = 1;
SELECT a FROM foo WHERE b = 1 LIMIT 100,10;

另外一種是使用SQL_CALC_FOUND_ROWS
復制代碼 代碼如下:
SELECT SQL_CALC_FOUND_ROWS a FROM foo WHERE b = 1 LIMIT 100, 10;
SELECT FOUND_ROWS();

第二種方式調用SQL_CALC_FOUND_ROWS之后會將WHERE語句查詢的行數放在FOUND_ROWS()之中,第二次只需要查詢FOUND_ROWS()就可以查出有多少行了。


討論這兩種方法的優缺點:
首先原子性講,第二種肯定比第一種好。第二種能保證查詢語句的原子性,第一種當兩個請求之間有額外的操作修改了表的時候,結果就自然是不準確的了。而第二種則不會。但是非??上?,一般頁面需要進行分頁顯示的時候,往往并不要求分頁的結果非常準確。即分頁返回的total總數大1或者小1都是無所謂的。所以其實原子性不是我們分頁關注的重點。

下面看效率。這個非常重要,分頁操作在每個網站上的使用都是非常大的,查詢量自然也很大。由于無論哪種,分頁操作必然會有兩次sql查詢,于是就有很多很多關于兩種查詢性能的比較:

SQL_CALC_FOUND_ROWS真的很慢么?

http://hi.baidu.com/thinkinginlamp/item/b122fdaea5ba23f614329b14

To SQL_CALC_FOUND_ROWS or not to SQL_CALC_FOUND_ROWS?

http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/

老王這篇文章里面有提到一個covering index的概念,簡單來說就是怎樣才能只讓查詢根據索引返回結果,而不進行表查詢

具體看他的另外一篇文章:

MySQL之Covering Index

http://hi.baidu.com/thinkinginlamp/item/1b9aaf09014acce0f45ba6d3

實驗
結合這幾篇文章,做的實驗:

表:
復制代碼 代碼如下:
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;

注意下這里是使用b,a做了一個索引,所以查詢select * 的時候是不會用到covering index的,select a才會使用到covering index
復制代碼 代碼如下:
<?php

$host = '192.168.100.166';
$dbName = 'test';
$user = 'root';
$password = '';

$db = mysql_connect($host, $user, $password) or die('DB connect failed');
mysql_select_db($dbName, $db);

 
echo '==========================================' . "/r/n";

$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 . "/r/n";

echo '==========================================' . "/r/n";

$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 . "/r/n";

echo '==========================================' . "/r/n";

$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 * FROM foo WHERE b = 1 LIMIT 100,10");
}
$end = microtime(true);
echo $end - $start . "/r/n";

echo '==========================================' . "/r/n";

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

返回的結果:

和老王里面文章說的是一樣的。第四次查詢SQL_CALC_FOUND_ROWS由于不僅是沒有使用到covering index,也需要進行全表查詢,而第三次查詢COUNT(*),且select * 有使用到index,并沒進行全表查詢,所以有這么大的差別。

總結
PS: 另外提醒下,這里是使用MyISAM會出現三和四的查詢差別這么大,但是如果是使用InnoDB的話,就不會有這么大差別了。

所以我得出的結論是如果數據庫是InnoDB的話,我還是傾向于使用SQL_CALC_FOUND_ROWS

結論:SQL_CALC_FOUND_ROWS和COUNT(*)的性能在都使用covering index的情況下前者高,在沒使用covering index情況下后者性能高。所以使用的時候要注意這個。

php技術Mysql中分頁查詢的兩個解決方法比較,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 97视频免费观看2区 97视频免费观看 | 野花日本大全免费高清完整版 | 日本亚洲欧洲免费旡码 | 久久99re6热在线播放 | 亚洲精品国产专区91在线 | 国产一区内射最近更新 | 久久婷婷五月综合色情 | 欧美美女一区二区三区 | 国产色婷婷亚洲99精品 | beeg xxx日本老师 | 久久99热这里只有精品66 | 人妻系列合集 | 蜜芽在线播放免费人成日韩视频 | 欧美兽交YOYO | 国产不卡在线观看视频 | 欧美特级特黄AAAAA片 | 日本国产黄色片 | 亚洲精品影院久久久久久 | 久久免费看少妇级毛片蜜臀 | 午夜福利体验免费体验区 | 黑人操白逼 | 色欲AV精品人妻一区二区三区 | 伊人久久国产精品 | 宿舍BL 纯肉各种PLAY H | 啪啪激情婷婷久久婷婷色五月 | 韩日美无码精品无码 | 狠狠色狠狠色综合日日32 | 欧美成人中文字幕在线视频 | 果冻传媒2021精品在线观看 | 风流少妇BBWBBW69视频 | 久久热这里只有 精品 | 国产精品麻豆a在线播放 | 超碰高清熟女一区二区 | 无码毛片内射白浆视频 | 囯产精品一区二区三区线 | 好吊射视频988gaocom | 亚洲午夜久久久精品影院 | 亚洲中文 字幕 国产 综合 | 国产成人cao在线 | 成人国产精品免费网站 | 午夜DV内射一区区 |