mysql騷操作 Mysql騷操作 優化大分頁查詢

2021-10-20 23:34:33 字數 3232 閱讀 9973

系統結構如上圖。經過排查是因為系統b拉取資料時間太長導致的推送超時。

系統b拉取資料的方法是根據_tiemstamp(資料操作時間)分頁查詢系統a的介面,即:

1select?欄位名2from?表名3where?_timestamp?>=?begintime?and?_timestamp?<=?endtime?4limit?n,?m;

由於該資料是從其他資料來源中匯入的,所以_timestamp這個字段值幾乎相同,這就導致了在我們的查詢範圍內存在大約150萬的資料。一般遇到這種情況,首先想到的就是是否需要給_timestamp新增索引,這張表上是存在_timestamp索引的。那麼為什麼還會出現這個問題呢?這就要從分頁查詢本身說起了。

分頁查詢的效能瓶頸

b+樹簡述

首先我們要了解innodb儲存引擎中的b+數索引。這裡我簡單總結一下:

上圖是一顆b+樹,通過觀察我們可以發現它的一些特點:

??1.每個節點中子節點個個數不能少於m/2個,不能大於m個(b+樹是一顆m叉樹,圖中m=3)

??2.根節點的節點個數可以超過m/2個,這是乙個例外

上述兩點特性是為了保證b+樹的查詢效率。

節點數超過m越多,在總節點數相同的情況下,樹的高度h就越小,此時m叉數就會向鍊錶退化(o(logn)->o(n))。 ??節點數小於m/2越多,在總節點數相同的情況下,樹的高度h就越高,此時查詢資料,就需要經歷更多次的io

??3.m叉樹非葉子節點只儲存索引,不儲存資料

??4.通過鍊錶將葉子節點串聯在一起,這樣可以方便按區間查詢。

b+比起二叉查詢樹,有什麼優勢?

更矮,這就減少了io次數。

由於非葉子節點不儲存資料,上圖查詢任何資料,都需要3次io,查詢效能更穩定

由於葉子節點使用了鍊錶連線,範圍查詢更簡便。

分頁查詢過程

1.首先通過非主鍵索引查詢出所有條件的主鍵

2.通過主鍵索引,定位到資料

3.不斷重複上述操作

4.根據分頁條件,確定返回資料的啟始位置以及資料量

5.返回資料

可以看出,初始位置值越大,定位時需要查詢的資料就越多,查詢效率也會越低

測試集為了測試優化效果,我準備了150萬測試資料(需要跑幾分鐘)。

1# 建表語句

2create table `test`(

3 `id` bigint(20) not null auto_increment comment 『主鍵『,

4 `name` varchar(512) not null default 『無『 comment 『建立人『,

5 `_timestamp` timestamp not null default current_timestamp on update current_timestamp comment 『更新時間『,

6 primary key (`id`),

7 key `ix_timestamp` (`_timestamp`)

8) engine=innodb default charset=utf8 comment=『測試表『;

11# 通過儲存過程匯入資料

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 ;

25call idata();

??接著,我們看一下使用索引的情況下,分頁查詢語句的耗時情況。

??可以看出,在使用索引的情況下,無論初始位置是0,還是145萬,mysql都會掃瞄所有符合條件的資料,然後找到初始位置的資料,向後查偏移量個資料,最後返回。

這兩條語句的執行速度差距非常大,大約3個數量級(0.00sec,10 sec)

解決方法

針對於limit,有很多優化的方法,比如前端加快取、或者使用分頁載入的方式展示資料。(大部分使用者請求資料的初始開始都不會很大)。在我們的使用場景中,調大超時時間的閾值也是可以的。

但是回到問題本身,問題出現的原因就是分頁語句隨著初始位置的增加,會有效能問題,所以治本的辦法,是對這個語句進行優化,有兩個優化方法:

1 延遲關聯法:

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

然後再通過主鍵索引查詢資料,這就省去了遍歷資料找初始位置資料的過程

??通過延遲關聯的方法,我們將10sec的耗時降低到了1.58sec,優化了將近1個數量級。

2 主鍵閾值法

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

然後再根據閾值,取資料即可,同樣省去了遍歷資料找初始位置資料的過程

通過主鍵閾值法的方法,我們將10sec的耗時降低到了1.12sec,優化了1個數量級

最後??1.文中優化效果是僅憑藉呼叫一次sql的耗時給出的,並不科學,僅僅是為了讓大家有乙個直觀的概念。

??2.無論是延遲關聯法,還是主鍵閾值法。思想都是一樣的,先把符合條件的主鍵找到,然後通過主鍵去定位符合條件的資料,這裡優化了2個點:1.通過索引覆蓋避免了回表;2.通過主鍵直接定位資料的方法,省去了在資料集中查詢初始位置的過程

??3.優化的效果隨資料量增加而增強。萬級別的資料優化效果可能並不明顯。

原文:

MySQL相關騷操作

windows找不到mysql服務了 命令列進入安裝目錄的bin下.輸入 mysqld.exe install,回車.進入服務介面中選中mysql選項,右鍵屬性將 啟動型別 設定為 自動 服務狀態 設定為 已啟動 windows無法啟動mysql 1053 第一步 mysqld nt remove ...

Mysql騷操作 優化大分頁查詢

系統結構如上圖。經過排查是因為系統b拉取資料時間太長導致的推送超時。系統b拉取資料的方法是根據 tiemstamp 資料操作時間 分頁查詢系統a的介面,即 1select 欄位名2from 表名3where timestamp begintime and timestamp endtime 4lim...

Pandas各種騷操作

stack unstack pivot pivot table 假如以下資料是5個公司4年分別的銷售額 pivot 函式 pivot table 函式 pivot table 函式和pivot 函式類似,但功能更為強大。例如如下資料 a在one中重複了兩次,被預設取了平均值,a在two中不存在,值為...