日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

mysql 大分页查询优化_Mysql骚操作:优化大分页查询

發(fā)布時(shí)間:2025/3/15 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 大分页查询优化_Mysql骚操作:优化大分页查询 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景

系統(tǒng)結(jié)構(gòu)如上圖。經(jīng)過(guò)排查是因?yàn)橄到y(tǒng)B拉取數(shù)據(jù)時(shí)間太長(zhǎng)導(dǎo)致的推送超時(shí)。

系統(tǒng)B拉取數(shù)據(jù)的方法是根據(jù)_tiemstamp(數(shù)據(jù)操作時(shí)間)分頁(yè)查詢(xún)系統(tǒng)A的接口,即:

1SELECT?字段名2FROM?表名3WHERE?_timestamp?>=?beginTime?AND?_timestamp?<=?endTime?4LIMIT?n,?m;

由于該數(shù)據(jù)是從其他數(shù)據(jù)源中導(dǎo)入的,所以_timestamp這個(gè)字段值幾乎相同,這就導(dǎo)致了在我們的查詢(xún)范圍內(nèi)存在大約150萬(wàn)的數(shù)據(jù)。一般遇到這種情況,首先想到的就是是否需要給_timestamp添加索引,這張表上是存在_timestamp索引的。那么為什么還會(huì)出現(xiàn)這個(gè)問(wèn)題呢?這就要從分頁(yè)查詢(xún)本身說(shuō)起了。

分頁(yè)查詢(xún)的性能瓶頸

B+樹(shù)簡(jiǎn)述

首先我們要了解InnoDB存儲(chǔ)引擎中的B+數(shù)索引。這里我簡(jiǎn)單總結(jié)一下:

上圖是一顆B+樹(shù),通過(guò)觀(guān)察我們可以發(fā)現(xiàn)它的一些特點(diǎn):

1.每個(gè)節(jié)點(diǎn)中子節(jié)點(diǎn)個(gè)個(gè)數(shù)不能少于m/2個(gè),不能大于m個(gè)(B+樹(shù)是一顆m叉樹(shù),圖中m=3)

2.根節(jié)點(diǎn)的節(jié)點(diǎn)個(gè)數(shù)可以超過(guò)m/2個(gè),這是一個(gè)例外

上述兩點(diǎn)特性是為了保證B+樹(shù)的查詢(xún)效率。

節(jié)點(diǎn)數(shù)超過(guò)m越多,在總節(jié)點(diǎn)數(shù)相同的情況下,樹(shù)的高度h就越小,此時(shí)m叉數(shù)就會(huì)向鏈表退化(O(logn)->O(n))。 ??節(jié)點(diǎn)數(shù)小于m/2越多,在總節(jié)點(diǎn)數(shù)相同的情況下,樹(shù)的高度h就越高,此時(shí)查詢(xún)數(shù)據(jù),就需要經(jīng)歷更多次的IO

3.m叉樹(shù)非葉子節(jié)點(diǎn)只存儲(chǔ)索引,不存儲(chǔ)數(shù)據(jù)

4.通過(guò)鏈表將葉子節(jié)點(diǎn)串聯(lián)在一起,這樣可以方便按區(qū)間查找。

B+比起二叉查找樹(shù),有什么優(yōu)勢(shì)?

更矮,這就減少了IO次數(shù)。

由于非葉子節(jié)點(diǎn)不存儲(chǔ)數(shù)據(jù),上圖查詢(xún)?nèi)魏螖?shù)據(jù),都需要3次IO,查詢(xún)性能更穩(wěn)定

由于葉子節(jié)點(diǎn)使用了鏈表連接,范圍查詢(xún)更簡(jiǎn)便。

分頁(yè)查詢(xún)過(guò)程

1.首先通過(guò)非主鍵索引查詢(xún)出所有條件的主鍵

2.通過(guò)主鍵索引,定位到數(shù)據(jù)

3.不斷重復(fù)上述操作

4.根據(jù)分頁(yè)條件,確定返回?cái)?shù)據(jù)的啟始位置以及數(shù)據(jù)量

5.返回?cái)?shù)據(jù)

可以看出,初始位置值越大,定位時(shí)需要查詢(xún)的數(shù)據(jù)就越多,查詢(xún)效率也會(huì)越低

測(cè)試集

為了測(cè)試優(yōu)化效果,我準(zhǔn)備了150萬(wàn)測(cè)試數(shù)據(jù)(需要跑幾分鐘)。

1# 建表語(yǔ)句

2CREATE TABLE `test`(

3 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',

4 `name` varchar(512) NOT NULL DEFAULT '無(wú)' COMMENT '創(chuàng)建人',

5 `_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時(shí)間',

6 PRIMARY KEY (`id`),

7 KEY `ix_timestamp` (`_timestamp`)

8) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='測(cè)試表';

9

10

11# 通過(guò)存儲(chǔ)過(guò)程導(dǎo)入數(shù)據(jù)

12drop procedure idata;

13delimiter ;;

14create procedure idata()

15begin

16 declare i int;

17 set i=1;

18 while(i<=1500000)do

19 insert into test values(i, i, now());

20 set i=i+1;

21 end while;

22end;;

23delimiter ;

24

25call idata();

接著,我們看一下使用索引的情況下,分頁(yè)查詢(xún)語(yǔ)句的耗時(shí)情況。

可以看出,在使用索引的情況下,無(wú)論初始位置是0,還是145萬(wàn),Mysql都會(huì)掃描所有符合條件的數(shù)據(jù),然后找到初始位置的數(shù)據(jù),向后查偏移量個(gè)數(shù)據(jù),最后返回。

這兩條語(yǔ)句的執(zhí)行速度差距非常大,大約3個(gè)數(shù)量級(jí)(0.00sec,10 sec)

解決方法

針對(duì)于limit,有很多優(yōu)化的方法,比如前端加緩存、或者使用分頁(yè)加載的方式展示數(shù)據(jù)。(大部分用戶(hù)請(qǐng)求數(shù)據(jù)的初始開(kāi)始都不會(huì)很大)。在我們的使用場(chǎng)景中,調(diào)大超時(shí)時(shí)間的閾值也是可以的。

但是回到問(wèn)題本身,問(wèn)題出現(xiàn)的原因就是分頁(yè)語(yǔ)句隨著初始位置的增加,會(huì)有性能問(wèn)題,所以治本的辦法,是對(duì)這個(gè)語(yǔ)句進(jìn)行優(yōu)化,有兩個(gè)優(yōu)化方法:

1 延遲關(guān)聯(lián)法:

我們先查詢(xún)出符合要求的主鍵(由于查詢(xún)的字段有索引,該索引的葉子節(jié)點(diǎn)就是主鍵,通過(guò)索引覆蓋我們可以省去一次回表操作。)

然后再通過(guò)主鍵索引查詢(xún)數(shù)據(jù),這就省去了遍歷數(shù)據(jù)找初始位置數(shù)據(jù)的過(guò)程

通過(guò)延遲關(guān)聯(lián)的方法,我們將10sec的耗時(shí)降低到了1.58sec,優(yōu)化了將近1個(gè)數(shù)量級(jí)。

2 主鍵閾值法

如果你的主鍵是自增的,那么就可以通過(guò)條件推算出符合條件的主鍵最大值&最小值(這里也是通過(guò)索引覆蓋省去了一次回表操作)

然后再根據(jù)閾值,取數(shù)據(jù)即可,同樣省去了遍歷數(shù)據(jù)找初始位置數(shù)據(jù)的過(guò)程

通過(guò)主鍵閾值法的方法,我們將10sec的耗時(shí)降低到了1.12sec,優(yōu)化了1個(gè)數(shù)量級(jí)

最后

最后對(duì)文章做一下補(bǔ)充說(shuō)明:

1.文中優(yōu)化效果是僅憑借調(diào)用一次SQL的耗時(shí)給出的,并不科學(xué),僅僅是為了讓大家有一個(gè)直觀(guān)的概念。

2.無(wú)論是延遲關(guān)聯(lián)法,還是主鍵閾值法。思想都是一樣的,先把符合條件的主鍵找到,然后通過(guò)主鍵去定位符合條件的數(shù)據(jù),這里優(yōu)化了2個(gè)點(diǎn):1.通過(guò)索引覆蓋避免了回表;2.通過(guò)主鍵直接定位數(shù)據(jù)的方法,省去了在數(shù)據(jù)集中查詢(xún)初始位置的過(guò)程

3.優(yōu)化的效果隨數(shù)據(jù)量增加而增強(qiáng)。萬(wàn)級(jí)別的數(shù)據(jù)優(yōu)化效果可能并不明顯。

總結(jié)

以上是生活随笔為你收集整理的mysql 大分页查询优化_Mysql骚操作:优化大分页查询的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。