六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

詳細說明在mysql查詢時,offset過大影響性能的原因與優(yōu)化方法

[摘要]mysql查詢使用select命令,配合limit,offset參數可以讀取指定范圍的記錄。本文將介紹mysql查詢時,offset過大影響性能的原因及優(yōu)化方法。 準備測試數據表及數據1.創(chuàng)建表CR...

mysql查詢使用select命令,配合limit,offset參數可以讀取指定范圍的記錄。本文將介紹mysql查詢時,offset過大影響性能的原因及優(yōu)化方法。

準備測試數據表及數據

1.創(chuàng)建表

CREATE TABLE `member` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL COMMENT '姓名', `gender` tinyint(3) unsigned NOT NULL COMMENT '性別', PRIMARY KEY (`id`), KEY `gender` (`gender`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.插入1000000條記錄

<?php
$pdo = new PDO("mysql:host=localhost;dbname=user","root",'');for($i=0; $i<1000000; $i++){    $name = substr(md5(time().mt_rand(000,999)),0,10);    $gender = mt_rand(1,2);    $sqlstr = "insert into member(name,gender) values('".$name."','".$gender."')";    $stmt = $pdo->prepare($sqlstr);    $stmt->execute();}
?>mysql> select count(*) from member;
+----------+  count(*)  
+----------+   1000000  
+----------+1 row in set (0.23 sec)


3.當前數據庫版本

mysql> select version();
+-----------+  version()  
+-----------+  5.6.24     
+-----------+1 row in set (0.01 sec)


分析offset過大影響性能的原因

1.offset較小的情況

mysql> select * from member where gender=1 limit 10,1;
+----+------------+--------+  id   name         gender  
+----+------------+--------+  26   509e279687        1  
+----+------------+--------+1 row in set (0.00 sec)mysql> select * from member where gender=1 limit 100,1;
+-----+------------+--------+  id    name         gender  
+-----+------------+--------+  211   07c4cbca3a        1  
+-----+------------+--------+1 row in set (0.00 sec)mysql> select * from member where gender=1 limit 1000,1;
+------+------------+--------+  id     name         gender  
+------+------------+--------+  1975   e95b8b6ca1        1  
+------+------------+--------+1 row in set (0.00 sec)

當offset較小時,查詢速度很快,效率較高。

2.offset較大的情況

mysql> select * from member where gender=1 limit 100000,1;
+--------+------------+--------+  id       name         gender  
+--------+------------+--------+  199798   540db8c5bc        1  
+--------+------------+--------+1 row in set (0.12 sec)mysql> select * from member where gender=1 limit 200000,1;
+--------+------------+--------+  id       name         gender  
+--------+------------+--------+  399649   0b21fec4c6        1  
+--------+------------+--------+1 row in set (0.23 sec)mysql> select * from member where gender=1 limit 300000,1;
+--------+------------+--------+  id       name         gender  
+--------+------------+--------+  599465   f48375bdb8        1  
+--------+------------+--------+1 row in set (0.31 sec)

當offset很大時,會出現效率問題,隨著offset的增大,執(zhí)行效率下降。

分析影響性能原因

select * from member where gender=1 limit 300000,1;

因為數據表是InnoDB,根據InnoDB索引的結構,查詢過程為:

  • 通過二級索引查到主鍵值(找出所有gender=1的id)。

  • 再根據查到的主鍵值通過主鍵索引找到相應的數據塊(根據id找出對應的數據塊內容)。

  • 根據offset的值,查詢300001次主鍵索引的數據,最后將之前的300000條丟棄,取出最后1條。

不過既然二級索引已經找到主鍵值,為什么還需要先用主鍵索引找到數據塊,再根據offset的值做偏移處理呢?

如果在找到主鍵索引后,先執(zhí)行offset偏移處理,跳過300000條,再通過第300001條記錄的主鍵索引去讀取數據塊,這樣就能提高效率了。

如果我們只查詢出主鍵,看看有什么不同

mysql> select id from member where gender=1 limit 300000,1;
+--------+  id      
+--------+  599465  
+--------+1 row in set (0.09 sec)

很明顯,如果只查詢主鍵,執(zhí)行效率對比查詢全部字段,有很大的提升。

推測

只查詢主鍵的情況
因為二級索引已經找到主鍵值,而查詢只需要讀取主鍵,因此mysql會先執(zhí)行offset偏移操作,再根據后面的主鍵索引讀取數據塊。

需要查詢所有字段的情況
因為二級索引只找到主鍵值,但其他字段的值需要讀取數據塊才能獲取。因此mysql會先讀出數據塊內容,再執(zhí)行offset偏移操作,最后丟棄前面需要跳過的數據,返回后面的數據。

證實

InnoDB中有buffer pool,存放最近訪問過的數據頁,包括數據頁和索引頁。

為了測試,先把mysql重啟,重啟后查看buffer pool的內容。

mysql> select index_name,count(*) from information_schema.INNODB_BUFFER_PAGE where INDEX_NAME in('primary','gender') and TABLE_NAME like '%member%' group by index_name;
Empty set (0.04 sec)

可以看到,重啟后,沒有訪問過任何的數據頁。

查詢所有字段,再查看buffer pool的內容

mysql> select * from member where gender=1 limit 300000,1;
+--------+------------+--------+  id       name         gender  
+--------+------------+--------+  599465   f48375bdb8        1  
+--------+------------+--------+1 row in set (0.38 sec)mysql> select index_name,count(*) from information_schema.INNODB_BUFFER_PAGE where INDEX_NAME in('primary','gender') and TABLE_NAME like '%member%' group by index_name;
+------------+----------+  index_name   count(*)  
+------------+----------+  gender            261    PRIMARY          1385  
+------------+----------+2 rows in set (0.06 sec)

可以看出,此時buffer pool中關于member表有1385個數據頁,261個索引頁。

重啟mysql清空buffer pool,繼續(xù)測試只查詢主鍵

mysql> select id from member where gender=1 limit 300000,1;
+--------+  id      
+--------+  599465  
+--------+1 row in set (0.08 sec)mysql> select index_name,count(*) from information_schema.INNODB_BUFFER_PAGE where INDEX_NAME in('primary','gender') and TABLE_NAME like '%member%' group by index_name;
+------------+----------+  index_name   count(*)  
+------------+----------+  gender            263    PRIMARY            13  
+------------+----------+2 rows in set (0.04 sec)

可以看出,此時buffer pool中關于member表只有13個數據頁,263個索引頁。因此減少了多次通過主鍵索引訪問數據塊的I/O操作,提高執(zhí)行效率。

因此可以證實,mysql查詢時,offset過大影響性能的原因是多次通過主鍵索引訪問數據塊的I/O操作。(注意,只有InnoDB有這個問題,而MYISAM索引結構與InnoDB不同,二級索引都是直接指向數據塊的,因此沒有此問題 )。

InnoDB與MyISAM引擎索引結構對比圖

這里寫圖片描述


優(yōu)化方法

根據上面的分析,我們知道查詢所有字段會導致主鍵索引多次訪問數據塊造成的I/O操作。

因此我們先查出偏移后的主鍵,再根據主鍵索引查詢數據塊的所有內容即可優(yōu)化。

mysql> select a.* from member as a inner join (select id from member where gender=1 limit 300000,1) as b on a.id=b.id;
+--------+------------+--------+  id       name         gender  
+--------+------------+--------+  599465   f48375bdb8        1  
+--------+------------+--------+1 row in set (0.08 sec)

本篇文章講解了在mysql查詢時,offset過大影響性能的原因與優(yōu)化方法 ,更多相關內容請關注php中文網。

相關推薦:

關于php使用正則去除寬高樣式的方法

詳解文件內容去重及排序 的相關內容

解讀mysql大小寫敏感配置問題

以上就是詳解在mysql查詢時,offset過大影響性能的原因與優(yōu)化方法的詳細內容,更多請關注php中文網其它相關文章!


學習教程快速掌握從入門到精通的SQL知識。




主站蜘蛛池模板: 亚洲成人看片 | 天天欧美 | 日韩天堂网 | 日韩欧美亚洲综合久久影院d3 | 凸凹在线视频 | 人人入人人爱 | 青青草原免费在线 | 特级黄一级播放 | 天天看天天色 | 日韩亚射| 日韩高清性爽一级毛片免费 | 午夜国产福利在线 | 午夜日| 五月天婷婷网站 | 一级国产视频 | 四虎永久在线精品国产馆v视影院 | 日韩欧美国内 | 中日韩国语视频在线观看 | 亚洲码专区 | 天天做夜夜做久久做狠狠 | 亚洲性视频在线 | 亚洲va欧美ⅴa国产va影院 | 五月婷婷免费视频 | 日本天堂免费 | 日本欧美中文字幕 | 青春草视频在线免费观看 | 色黄视频在线观看 | 亚洲一一在线 | 一级毛片子 | 中文字幕在线色 | 伊人2233 | 天使萌一区二区三区免费观看 | 欧美性夜| 欧美无人区码卡二三卡四卡 | 四虎免费永久在线播放 | 青青青草视频在线观看 | 最新欧美伦禁片在线观看 | 日韩精品一区二区三区中文在线 | 在线国产二区 | 一级做a爰片性色毛片刺激 一级做a爰片欧美一区 | 天天干天天拍天天射天天添天天爱 |