成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么你的MySQL性能差?死代碼牽連問題解決了嗎?

數據庫 MySQL
MySQL存儲過程、函數和觸發器是開發人員常打交道的三大名詞,但是,這三個過程可能會對數據庫性能造成嚴重影響,尤其是函數中出現“死”代碼時,其它兩個過程都會受到牽連。以下是作者進行的一些基本測試,通過對比更好地衡量三者對數據庫性能的影響。

[[241905]]

MySQL存儲過程、函數和觸發器是開發人員常打交道的三大名詞,但是,這三個過程可能會對數據庫性能造成嚴重影響,尤其是函數中出現“死”代碼時,其它兩個過程都會受到牽連。以下是作者進行的一些基本測試,通過對比更好地衡量三者對數據庫性能的影響。

觸發器和存儲過程對性能影響的重要原因是函數“死”代碼。盡管所有開發人員都知道“死”代碼(永遠不會被運行的代碼)不應該出現在代碼行中,但可能并不清楚一行“死”代碼到底可以對性能造成多大影響。

“死”代碼會顯著減緩函數運行、存儲過程和觸發器的響應時間,因此我們必須認真清理不需要的代碼,以下是具體示例:

分析MySQL存儲過程函數

讓我們比較以下四個簡單的存儲函數(在MySQL 5.7中):

函數1

該函數只是聲明一個r變量并返回它的值,這是一個虛函數。

函數2

該函數調用另一個函數 levenshtein_limit_n(計算levenshtein距離)。但是,由于IF 1=2條件永遠不會成立,因此這段代碼永遠不會被執行,這與函數1的返回結果類似。  

函數3

 

函數3看起來很復雜,總共有四個條件,但因為這些條件永遠不會成立,因此同樣是“死”代碼調用,結果與函數2和函數1相同。 

函數4 

 

該函數與函數3情況相同,selectdoes_not_exit依舊不會被運行。 

雖然所有函數最終返回的r值都為0,但這四段函數的性能有非常大的差異,為了衡量性能變化,我們使用benchmark功能對性能進行測試,在運行相同的1M次之后,四個函數的性能結果如下:

  

我們可以看到fun 1只需要運行1.75 sec,具有一個死代碼調用的fun 2需要運行2.45 sec,而func 3(有四個永不執行的死代碼調用)運行速度比func 1()慢近3倍,func 3_nope()的響應時間與func 3()完全相同。 

可視化函數的所有系統調用 

要弄清楚函數調用過程發生了什么,我們可以使用performance_schema / sys模式創建一個帶有 ps_trace_thread() procedure的跟蹤。 

獲取MySQL連接的thread_id:

  

在另一個連接中通過thread_id = 49運行ps_trace_thread:

  

此時切換到原始連接(thread_id = 49)并運行:

 

sys.ps_trace_thread收集數據(10秒鐘,在此期間我運行了select func1()),然后它完成了集合并創建了點文件:

 

我為上面的所有函數重復了這些步驟,然后創建了命令圖表。 

結果如下: 

Func1():

 

Func2():

 

Func3():

 

正如我們所看到的,每個“if”檢查都有一個sp / jump_if_not調用,后跟一個打開表的語句。因此,解析“IF”條件就會對性能產生影響。 

對于MySQL 8.0,我們還可以看到存儲過程的MySQL源代碼文檔,這些文檔記錄了它的實現方式,如下: 

  • 流量分析優化; 
  • 生成代碼后,優化低級sp_instr指令。 

優化主要集中在兩方面: 

  • 死代碼刪除; 
  • 跳轉快捷方式。  

這兩個優化是一起執行的,因為它們都涉及圖表中流量分析的問題,代表生成的代碼。實現這些優化的代碼是sp_head :: optimize()。 

但是,這并不能解釋為什么會執行“opening tables”,因此,我向官網提交了一個bug——MySQL Bug #91585。

MySQL Bug #91585鏈接:

https://bugs.mysql.com/bug.php?id=91585 

“死”代碼如何影響觸發器性能? 

當然,如果我們執行的函數不太多,我們可能注意不到這些性能上的差異,但是它會在觸發器內部產生影響。假設我們在表上有一個觸發器,每次更新該表時,它都會執行觸發器來更新字段。比如,假設我們有一個名為“form”的表,我們只需要更新它的創建日期:

 

現在我們創建一個觸發器,它將調用我們的虛函數func1():

 

請記住:重復更新不會更改新的結果,因為我們沒有在觸發器中做任何事情。

  

如果再添加一個虛擬觸發器就會增加兩倍的開銷,即便觸發器沒有運行任何函數,同樣會引起減速:

 

現在,讓我們使用func3(它具有“死”代碼,但功能相當于func1):

  

如果,我們從觸發器內的函數func3運行代碼(而不是調用函數)將加快更新速度:

  

內存分配 

即使代碼永遠不會被運行,MySQL仍然需要分析每次執行解析存儲的過程或觸發器代碼,并預先為其留出足夠的內存,這可能會導致內存泄漏,比如MySQL Bug #86821所描述的。 

參考鏈接:https://bugs.mysql.com/bug.php?id=86821 

結論 

存儲過程和觸發器事件在執行時會被解析,即使是永不運行的“死”代碼也會顯著影響批量操作的性能(例如,在觸發器內運行時)。這意味著通過設置“flag”來禁用觸發器(例如,if @trigger_disable =0 then ...)仍然會影響批量操作的性能。 

 

責任編輯:龐桂玉 來源: DBAplus社群
相關推薦

2024-10-07 08:29:59

2010-04-13 14:25:24

Oracle問題解決

2010-05-11 12:57:45

MySQL數據庫編碼

2010-05-05 14:20:46

AIX CDE

2010-05-13 17:33:24

MySQL索引

2011-06-13 16:16:32

Qt 中文問題

2011-06-27 16:44:59

Qmake

2010-04-28 18:01:15

Unix系統

2010-06-17 11:35:24

Ubuntu 修復Gr

2011-08-10 13:46:36

Navicat MySMySQL

2009-06-30 14:02:00

Struts亂碼Eclipse

2009-02-26 11:13:41

Weblogic中間件JSP

2011-03-18 18:47:34

QtMySQL

2011-08-25 18:35:07

Linux cron執

2010-05-05 10:25:24

Unix操作系統

2011-11-28 22:45:19

Nginxsession

2009-12-28 10:56:45

WPF Image

2009-08-14 13:49:58

Rails中文問題

2012-05-09 10:08:41

跨機房

2011-01-21 14:13:10

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美三级成人理伦 | 天天干免费视频 | 欧美日韩一区二区视频在线观看 | 成人亚洲视频 | 欧美日韩三区 | 国产精久久久 | 色婷婷婷婷色 | 国产精品亚洲综合 | 午夜精品一区二区三区在线 | 91精品国产92 | 精品三区 | 免费黄色片在线观看 | 超碰成人免费 | 国产香蕉视频 | 国产日韩欧美在线 | 在线播放中文字幕 | 中文字幕一区二区三区不卡 | 成人免费看黄网站在线观看 | 国产精品久久久久久久久久久久冷 | 久久精品屋 | 久久av一区二区 | 午夜影院官网 | 久久久久久国产 | 日韩一区二区在线视频 | 黄色大片免费观看 | 成人免费视频 | 亚洲精品欧美一区二区三区 | 亚洲国产一区视频 | 影音先锋成人资源 | 国产福利在线 | 久久国产精品免费视频 | 四虎成人免费电影 | 99视频在线播放 | 一区二区在线不卡 | 97精品超碰一区二区三区 | 久久国产精品一区二区三区 | 特级毛片 | 日本久久网 | 天天综合网天天综合 | 婷婷色国产偷v国产偷v小说 | 中文字幕在线不卡播放 |