MySQL之性能剖析和Schema與數據類型優化(一)

性能剖析總結

  • 1.定義性能最有效的方法是響應時間
  • 2.如果無法測量就無法有效地優化,所以性能優化工作需要基于高質量、全方位及完整的響應時間測量
  • 3.測量的最佳開始點是應用程序,而不是數據庫。即使問題出在底層的數據庫,借助良好的測量也可以很容易地發現問題
  • 4.大多數系統無法完整地測量,測量有時候也會有錯誤的結果。但也可以想辦法繞過一些限制,并得到好的結果(但是要能意識到所使用的方法的缺陷和不確定性在哪里)
  • 5.完整的測量會產生大量需要分析的數據,所以需要用到剖析器。這是最佳的工具,可以幫助將重要的問題冒泡到前面,這樣就可以決定從哪里開始分析會比較好
  • 6.剖析報告是一種匯總信息,掩蓋和丟棄了太多細節。而且它不會告訴你缺少了什么,所以完全依賴剖析報告也是不明智的
  • 7.有兩種消耗時間的操作:工作或者等待。大多數剖析器只能測量因為工作而消耗的時間,所以等待分析有時候是很有用的補充,尤其是當CPU利用率很低但工作卻一直無法完成的時候
  • 8.優化和提升是兩回事。當繼續提升的成本超過收益的時候,應當停止優化
  • 9.注意你的直覺,但應該只根據直覺來指導解決問題的思路,而不是用于確定系統的問題。決策應當盡量基于數據而不是感覺。

總的來說,解決性能問題的方法首先是要澄清問題,然后選擇合適的技術來解答這些問題。如果你想嘗試提升服務器的總體性能,那么一個比較好的七點是將所有查詢記錄到日志中,然后利用pt-query-digest工具生成系統級別的剖析報告。如果是要追查某些性能低下的查詢,記錄和剖析得方法也會有幫助。可以把精力放在尋找哪些消耗時間最多的、導致了糟糕的用戶體驗的,或者那些高度變化的,抑或有奇怪的響應時間直方圖的查詢。當找到了這些"壞"查詢時,要鉆取pt-query-digest報告中包含的該查詢的詳細信息,或者使用SHOW PROFILE及其他諸如EXPLAIN這樣的工具。

如果找不到這些查詢性能低下的原因,那么也可能時遇到了服務器級別的性能問題。這是,可以較高精度測量和回直服務器狀態計數器的細節信息。如果通過這樣的分析重現了問題,則應該通過同樣的數據制定一個可靠的觸發條件,來收集更多的診斷數據。多花費一點時間來確定可靠的觸發條件,盡量避免漏檢或者誤報。如果已經可以捕獲故障活動期間的數據,但還是無法找到其根本原因,則要么嘗試捕獲更多的數據,要么嘗試尋求幫助。
我們無法完整地測量工作系統,但說到底它們都是某種狀態機,所以只要足夠細心,邏輯清晰并且堅持下去,通常來說都能得到想要的結果。要注意的時不要把原因和結果搞混了,而且在確認問題之前也不要隨便針對系統做變動。
理論上純粹的自頂向下的方法分析和詳盡的測量只是理想的情況,而我們常常需要處理的是真實系統。真實系統是復雜且無法充分測量的,所以我們只能根據情況盡力而為。使用諸如pt-query-digest和MySQL企業監控器的查詢分析其這樣的工具并不完美,通常都不會給出問題根源的直接證據。但真的掌握了以后,已經足以完成大部分的優化診斷工作了。

Schema與數據類型優化

概述

良好的邏輯設計和物理設計是高性能的基石,應該根據系統將要執行的查詢語句來設計schema,這往往需要權衡各種因素。例如,反范式的設計可以加快某些類型的查詢,但同時可能使另一些類型的查詢變慢。比如添加計數器和匯總表是一種很好的優化查詢的方式,但這些表的維護成本可能會很高。MySQL獨有的特性和實現細節對性能的影響也很大。

選擇優化的數據類型

MySQL支持的數據類型非常多,選擇正確的數據類型對于獲取高性能至關重要。不管存儲哪種類型的數據,下面幾個簡單的原則都有助于做出更好的選擇。

  • 1.更好的通常更好
    一般情況下,應該盡量使用可以正確存儲數據更小的數據類型(例如只需要存0~200,tinyint unsigned更好)。更小的數據類型通常更快,因為它們占用更少的磁盤、內存和CPU緩存,并且處理時需要的CPU周期也更少。
    但是要確保沒有嘀咕需要存儲的值范圍,因為在schema中的多個地方增加數據類型的范圍是一個非常耗時和痛苦的操作。如果無法確定哪個數據類型是最好的,就選擇你認為不會超過范圍的最小類型。(如果系統不是很忙或者存儲的數據量不多,或者是在可以輕易修改設計的早期階段,那之后修改數據類型也比較容易)
  • 2.簡單就好
    簡單數據類型的操作通常需要更少的CPU周期。例如,整型比字符操作代價更低,因為字符集和校對規則(排序規則)使字符比較比整型比較更復雜。有兩個例子:一個是應該使用mySQL的內建類型(date,time,datetime)而不是字符串來存儲日期和時間,另外一個是應該使用整型存儲IP地址。
  • 3.盡量避免NULL
    很多表都包含可為NULL(空值)的列,即使應用程序并不需要保存NULL也是如此,這是因為可為NULL是列的默認屬性。通常情況下最好指定列為NOT NULL,除非真的需要存儲NULL值。如果查詢中包含可為NULL的列,對MySQL來說更難優化,因為可為NULL的列使得索引、索引統計和值比較都更復雜。可為NULL的列會使用更多的存儲空間,在MySQL里也需要特殊處理。當可為NULl的列被索引時,每個索引記錄需要一個額外的字節,在MyISAM里甚至還可能導致固定大小的索引(例如只有一個整數列的索引)變成可變大小的索引。
    通常把可為NULl的列改為NOT NULL帶來的性能提升比較小,所以(調優時)沒有必要首先在現有schema中查找并修改掉這種情況,除非確定這回導致問題。但是,如果計劃在列上鍵索引,就應該盡量避免設計成可為NULL的列。
    當然也有例外,例如值得一提的時,InnoDB使用單獨的位(bit)存儲NULL值,所以對于稀疏數據(很多值為NULL,只有少數行的列有非NULL值)有很好的空間效率。但這一點不適用于MyISAM

在為列選擇數據類型時,第一步需要確定合適的大類型:數字、字符串、時間等。這通常是很簡單的。但是我們會提到一些特殊的不是那么直觀的例子。
下一步是選擇具體類型。很多MySQL的數據類型可以存儲相同類型的數據,這是存儲的長度和范圍不一樣、允許的精度不同,或者需要的物理空間(磁盤和內存空間)不同,相同大類型的不同子類型數據有時也有一些特殊的行為和屬性。
然而TIMESTAMP只使用DATETIME一半的存儲空間,并且會根據時區變化,具有特殊的自動更新能力。另一方面,TIMESTAMP允許的時間范圍要小得多,有時候它的特殊能力會成為阻礙。

整數類型

有兩種類型的數字:整數(whole number)和實數(real number)。如果存儲整數,可以使用這幾種整數類型:TINYINT,SMALLINT, MEDIUMINT,INT,BIGINT.分別使用8,16,24,32,64存儲空間。它們可以存儲的值的范圍從-2(N-1)到2(N-1)-1,其中N是存儲空間的位數。
整數類型有可選的UNSIGNED屬性,表示不允許負值,這大致可以使正數的上限提高已被。例如TINYINT UNSIGNED可以存儲的范圍是0255,而TINYINY的存儲范圍是-128127.
有符號和無符號類型使用相同的存儲空間,并具有相同的性能,因此可以根據實際情況選擇合適的類型。你的選擇決定MySQL是怎么在內存和磁盤中保存數據的,然而,整數計算一半使用64位的BIGINT整數,即使在32位環境也是如此。(一些聚合函數是例外,它們使用DECIMAL或者DOUBLE進行計算)。
MySQL可以為整數類型指定寬度,例如INT(11),對大多數應用這是沒有意義的,他不會限制值得合法范圍,只是規定了MySQL的一些交互工具(例如MySQL命令行客戶端)用來顯示字符的個數。對于存儲和計算來說INT(1)和INT(20)是相同的。

實數類型

實數是帶有小數部分的數字。然而,它們不只是為了存儲小數部分;也可以使用DECIMAL存儲比BIGINT還大的整數。MySQL既支持精確類型,也支持不精確類型。
FLOAT和DOUBLE類型支持使用標準的浮點運算進行近似計算。如果需要直到浮點運算時怎么計算的,則需要研究所使用的平臺的浮點數的具體實現。DECIMAL類型用于存儲精確的小數。在MySQL 5.0和更高版本,DECIMAL類型支持精確計算。MySQL4.1及更早版本則使用浮點運算來實現DECIMAL的計算,這樣做會因為精度損失導致一些奇怪的結果。在這些版本的MySQL中,DECIMAL只是一個"存儲類型"。
因為CPU不支持對DECIMAL的直接計算,所以在MySQL5.0以及更高版本中,MySQL服務器自身實現了DECIMAL的高精度計算。相對而言,CPU直接支持原生浮點計算,所以浮點運算明顯更快。
浮點和DECIMAL類型都可以指定精度。對DECIMAL列,可以指定小數點前后所允許的最大位數。這會影響列的空間消耗。MySQL5.0和更高版本將數字打包保存到一個二進制字符串中(每4個字節存9個數字)。例如DECIMAL(18,9)小數點兩邊將個存儲9個數字,一共使用9個字節:小數點前的數字用4個字節,小數點后的數字用4個字節,小數點本身占1個字節。
MySQL5.0和更高版本中的DECIMAL類型允許最多65個數字。而早期的MySQL版本中,這個限制時254個數字,并且保存為未壓縮的字符串(每個數字一個字節)。然而,這些(早期)版本實際上并不能在計算中使用這么大的數字,因為DECIMAL只是一種存儲格式,在計算中DECIMAL會轉換為DOUBLE類型。
有多種方法可以指定浮點列所需要的精度,這回使得MySQL悄悄選擇不同的數據類型,或者在存儲時對值進行取舍。這些精度定義時非標準的,所以建議只指定數據類型,不指定精度。
浮點類型在存儲同樣范圍的值時,通常比DECIMAL使用更少的空間。FLOAT使用4個字節存儲。DOUBLE只能用8個字節,相比FLOAT有更高的精度和更大的范圍。和整數類型一樣,能選擇的只是存儲類型;MySQL使用DOUBLE作為內部浮點計算的類型。
因為需要額外的空間和計算開銷,所以應該盡量只在對小數進行精確計算時才使用DECIMAL——例如存儲財務數據。但在數據量比較大的時候,可以高鋁使用BIGINT代替DECIMAL,將需要存儲的貨幣單位根據小數的位數乘以相應的倍數即可。假設要存儲財務數據精確到萬分之一,則可以把所有金額乘以一百萬,然后將結果存儲在BIGINT里,這樣就可以同時避免浮點存儲計算不精確和DECIMAL精確計算代價高的問題

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/14587.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/14587.shtml
英文地址,請注明出處:http://en.pswp.cn/web/14587.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++系列-友元

&#x1f308;個人主頁&#xff1a;羽晨同學 &#x1f4ab;個人格言:“成為自己未來的主人~” 我們在之前的文章有提到友元&#xff0c;我們先來看下面的這段包含了友元的代碼&#xff1a; ??#define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace…

CLIP論文學習

學習來自B站bryanyzhu

jdk17安裝教程詳細(jdk17安裝超詳細圖文)

2021年9月14日JDK17 發布&#xff0c;其中不僅包含很多新語言功能&#xff0c;而且與舊版 JDK 相比&#xff0c;性能提升也非常明顯。與之前 LTS 版本的 JDK 8 和 JDK 11 相比&#xff0c;JDK17 的性能提升尤為明顯&#xff0c;本文將教你如何安裝 相比于JDK1.8&#xff0c;JD…

虛擬機網絡設置為橋接模式后未顯示網絡

本方法為&#xff0c;VMware配置正確&#xff0c;但在嘗試其他辦法后未能成功解決的人提供一種方法 本機的虛擬機使用NAT模式正常使用 但是使用橋接模式后重啟&#xff0c;未發現虛擬機內網絡設置,詳見下圖&#xff1a; 使用 ifconfig 查看網絡詳情 發現沒有ens33接口 查看硬…

雙非本科,逆襲中大廠的 Java 學習路線

從零基礎入門 Java&#xff0c;到最后秋招上岸&#xff0c;筆者也是花費了不少的經歷&#xff0c;也走了很多彎路。這一篇文章會記錄下真正有用的學習路線。 為什么要強調真正有用&#xff1f;網上的很多所謂從入門到求職&#xff0c;推薦的路線都超級長&#xff0c;零基礎的同…

LeetCode198:打家劫舍

題目描述 你是一個專業的小偷&#xff0c;計劃偷竊沿街的房屋。每間房內都藏有一定的現金&#xff0c;影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統&#xff0c;如果兩間相鄰的房屋在同一晚上被小偷闖入&#xff0c;系統會自動報警。 給定一個代表每個房屋存…

【學習筆記】Windows GDI繪圖(六)圖形路徑GraphicsPath詳解(中)

上一篇【學習筆記】Windows GDI繪圖(五)圖形路徑GraphicsPath詳解(上)介紹了GraphicsPath類的構造函數、屬性和方法AddArc添加橢圓弧、AddBezier添加貝賽爾曲線、AddClosedCurve添加封閉基數樣條曲線、AddCurve添加開放基數樣條曲線、基數樣條如何轉Bezier、AddEllipse添加橢圓…

華為校招機試 - 最久最少使用緩存(20240508)

題目描述 無線通信移動性需要在基站上配置鄰區(本端基站的小區 LocalCell 與周邊鄰基站的小區 NeighborCelI 映射)關系, 為了能夠加速無線算法的計算效率,設計一個鄰區關系緩存表,用于快速的通過本小區 LocalCell 查詢到鄰小區 NeighborCell。 但是緩存表有一定的規格限…

代碼隨想錄-Day07

454. 四數相加 II 給你四個整數數組 nums1、nums2、nums3 和 nums4 &#xff0c;數組長度都是 n &#xff0c;請你計算有多少個元組 (i, j, k, l) 能滿足&#xff1a; 0 < i, j, k, l < n nums1[i] nums2[j] nums3[k] nums4[l] 0 示例 1&#xff1a; 輸入&#x…

系統磁盤高級管理、lvm例子、創建pv、創建VG、創建lv、磁盤擴展

LVM&#xff1a; 邏輯卷&#xff0c;動態調整分區大小&#xff0c;擴展性好 創建pv pvcreate &#xff1a; 將實體 partition 創建成為 PV &#xff1b; pvscan &#xff1a; 搜尋目前系統里面任何具有 PV 的磁盤&#xff1b; pvdisplay &#xff1a; 顯示出目前系統上面…

GNSS仿真測試之三種常用坐標系與轉換

作者介紹 在當今的全球導航衛星系統&#xff08;GNSS&#xff09;技術領域&#xff0c;仿真測試是評估和驗證GNSS接收機性能的關鍵環節&#xff0c;全球導航衛星系統&#xff08;GNSS&#xff09;仿真測試是確保GNSS接收機和導航解決方案在實際部署前能夠正確、可靠地工作的關鍵…

【git】學習記錄: 貯藏功能

Git 貯藏修改是一種臨時存儲工作目錄中已經修改但尚未提交的更改的機制。通過貯藏修改&#xff0c;你可以將當前的工作目錄狀態保存起來&#xff0c;以便你可以在之后的時間點重新應用這些更改&#xff0c;或者在不同的分支間切換時避免沖突。 要使用 Git 貯藏修改&#xff0c…

Linux(centos)常用命令

Linux&#xff08;Centos&#xff09;常用命令使用說明文檔 切換到/home目錄下 使用cd命令切換目錄&#xff0c;例如&#xff1a; cd /home列出/home目錄下的所有文件 使用ls命令列出目錄下的文件和子目錄&#xff0c;例如&#xff1a; ls /home新建目錄dir1 使用mkdir命…

頭歌OpenGauss數據庫-I.復雜查詢第1關:獲取前N名成績

本關任務&#xff1a;編寫函數來實現獲取前N名成績的方法。 提示&#xff1a;前面的實驗沒有提供編寫自定義函數的示例&#xff0c;需要參考OpenGauss數據庫文檔學習自定義函數的使用。 score表內容如下&#xff1a; IdScore13.5223.6534.2343.8554.2363.65 --#請在BEGIN - END…

python windows 開發.exe程序筆記

import win32api import win32gui import win32con import time import tkinter as tk## pyinstaller --onefile t4.py 將python 代碼打包為windows可執行文件 .exe ## airtext 大漠 def clickGoogle():hw win32gui.FindWindow("Chrome_WidgetWin_1", "新標…

解決Redis 緩存雪崩(過期時間不一致) 和 緩存穿透(黑名單)

解決Redis 緩存雪崩&#xff08;過期時間不一致&#xff09; 和 緩存穿透&#xff08;黑名單&#xff09; public Product getdetailById(Integer id) {String key "product." id;// 查詢黑名單中是否有該keyBoolean b hashOperations.hasKey(PROODUCT_DETAIL_B…

算法 Hw7

Hw 7 Graph Algorithm 1 Edge detection2 Reachability3 Bitonic shortest paths 1 Edge detection 由 Cut Property 可知&#xff1a;如果 e 是從某個集合 S 到補集 V?S 的開銷最小的邊&#xff0c;則 e 一定所有最小生成樹中。 由 Cycle Property 可知&#xff1a;如果 e 是…

Gradle常見問題及總結

使用android studio開發項目&#xff0c;難免遇到gradle相關的錯誤&#xff0c;在此總結。 gradle插件與gradle home版本關系錯誤 參考更新 Gradle Gradle下載太慢 Index of /gradle/ (tencent.com) 是國內下載地址,手動下載對應版本即可 緩存不刷新 問題描述 maven發布…

jenkins插件之xunit

分析測試工具執行的結果&#xff0c;并圖形化&#xff0c;比如phpunit&#xff0c;phpstan,可分析junit格式的結果 安裝jenkins插件 搜索xunit并安裝 項目配置 配置 - Build Steps 您的項目 - 配置 - Build Steps, 新增 Run with timeout 超時時間根據實際情況配置 Build…

Day38 貪心算法part05

LC435無重疊區間(未掌握) 思路&#xff1a;先對數組進行排序&#xff0c;找到非重疊的區間的個數&#xff0c;然后區間的總數減去非重疊區間的個數即是需要移除的區間的個數與LC452用最少數量的箭引爆氣球類似&#xff0c;但是不同的是[1,2]和[2,3]在此題并不是重疊區間但是在…