• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    MySQL數據庫性能優化之索引優化_MySQL

    來源:懂視網 責編:小采 時間:2020-11-09 18:01:23
    文檔

    MySQL數據庫性能優化之索引優化_MySQL

    MySQL數據庫性能優化之索引優化_MySQL:bitsCN.com 這篇文章是以 MySQL 為背景,很多內容同時適用于其他關系型數據庫,需要有一些索引知識為基礎 優化目標 減少 IO 次數 IO永遠是數據庫最容易瓶頸的地方,這是由數據庫的職責所決定的,大部分數據庫操作中超過90%的時間都是 IO 操作所占用的,
    推薦度:
    導讀MySQL數據庫性能優化之索引優化_MySQL:bitsCN.com 這篇文章是以 MySQL 為背景,很多內容同時適用于其他關系型數據庫,需要有一些索引知識為基礎 優化目標 減少 IO 次數 IO永遠是數據庫最容易瓶頸的地方,這是由數據庫的職責所決定的,大部分數據庫操作中超過90%的時間都是 IO 操作所占用的,

    bitsCN.com

      這篇文章是以 MySQL 為背景,很多內容同時適用于其他關系型數據庫,需要有一些索引知識為基礎

      優化目標

      減少 IO 次數

      IO永遠是數據庫最容易瓶頸的地方,這是由數據庫的職責所決定的,大部分數據庫操作中超過90%的時間都是 IO 操作所占用的,減少 IO 次數是 SQL 優化中需要第一優先考慮,當然,也是收效最明顯的優化手段。

      降低 CPU 計算

      除了 IO 瓶頸之外,SQL優化中需要考慮的就是 CPU 運算量的優化了。order by, group by,distinct … 都是消耗 CPU 的大戶(這些操作基本上都是 CPU 處理內存中的數據比較運算)。當我們的 IO 優化做到一定階段之后,降低 CPU 計算也就成為了我們 SQL 優化的重要目標

      優化方法

      改變 SQL 執行計劃

      明確了優化目標之后,我們需要確定達到我們目標的方法。對于 SQL 語句來說,達到上述 2個目標的方法其實只有一個,那就是改變 SQL 的執行計劃,讓他盡量“少走彎路”,盡量通過各種“捷徑”來找到我們需要的數據,以達到 “減少 IO 次數” 和 “降低 CPU 計算” 的目標

      常見誤區

      count(1)和count(primary_key) 優于 count(*)

      很多人為了統計記錄條數,就使用 count(1) 和 count(primary_key) 而不是 count(*) ,他們認為這樣性能更好,其實這是一個誤區。對于有些場景,這樣做可能性能會更差,應為數據庫對 count(*) 計數操作做了一些特別的優化。

      count(column) 和 count(*) 是一樣的

      這個誤區甚至在很多的資深工程師或者是 DBA 中都普遍存在,很多人都會認為這是理所當然的。實際上,count(column) 和 count(*) 是一個完全不一樣的操作,所代表的意義也完全不一樣。

      count(column) 是表示結果集中有多少個column字段不為空的記錄

      count(*) 是表示整個結果集有多少條記錄

      select a,b from … 比 select a,b,c from … 可以讓數據庫訪問更少的數據量

      這個誤區主要存在于大量的開發人員中,主要原因是對數據庫的存儲原理不是太了解。

      實際上,大多數關系型數據庫都是按照行(row)的方式存儲,而數據存取操作都是以一個固定大小的IO單元(被稱作 block 或者 page)為單位,一般為4KB,8KB… 大多數時候,每個IO單元中存儲了多行,每行都是存儲了該行的所有字段(lob等特殊類型字段除外)。

      所以,我們是取一個字段還是多個字段,實際上數據庫在表中需要訪問的數據量其實是一樣的。

      當然,也有例外情況,那就是我們的這個查詢在索引中就可以完成,也就是說當只取 a,b兩個字段的時候,不需要回表,而c這個字段不在使用的索引中,需要回表取得其數據。在這樣的情況下,二者的IO量會有較大差異。

      order by 一定需要排序操作

      我們知道索引數據實際上是有序的,如果我們的需要的數據和某個索引的順序一致,而且我們的查詢又通過這個索引來執行,那么數據庫一般會省略排序操作,而直接將數據返回,因為數據庫知道數據已經滿足我們的排序需求了。

      實際上,利用索引來優化有排序需求的 SQL,是一個非常重要的優化手段

      延伸閱讀:MySQL ORDER BY 的實現分析,MySQL 中 GROUP BY 基本實現原理以及 MySQL DISTINCT 的基本實現原理這3篇文章中有更為深入的分析,尤其是第一篇

      執行計劃中有 filesort 就會進行磁盤文件排序

      有這個誤區其實并不能怪我們,而是因為 MySQL 開發者在用詞方面的問題。filesort 是我們在使用 explain 命令查看一條 SQL 的執行計劃的時候可能會看到在 “Extra” 一列顯示的信息。

      實際上,只要一條 SQL 語句需要進行排序操作,都會顯示“Using filesort”,這并不表示就會有文件排序操作。

      延伸閱讀:理解 MySQL Explain 命令輸出中的filesort,我在這里有更為詳細的介紹

      基本原則

      盡量少 join

      MySQL 的優勢在于簡單,但這在某些方面其實也是其劣勢。MySQL 優化器效率高,但是由于其統計信息的量有限,優化器工作過程出現偏差的可能性也就更多。對于復雜的多表 Join,一方面由于其優化器受限,再者在 Join 這方面所下的功夫還不夠,所以性能表現離 Oracle 等關系型數據庫前輩還是有一定距離。但如果是簡單的單表查詢,這一差距就會極小甚至在有些場景下要優于這些數據庫前輩。

      盡量少排序

      排序操作會消耗較多的 CPU 資源,所以減少排序可以在緩存命中率高等 IO 能力足夠的場景下會較大影響 SQL 的響應時間。

      對于MySQL來說,減少排序有多種辦法,比如:

      上面誤區中提到的通過利用索引來排序的方式進行優化

      減少參與排序的記錄條數

      非必要不對數據進行排序

      …

      盡量避免 select *

      很多人看到這一點后覺得比較難理解,上面不是在誤區中剛剛說 select 子句中字段的多少并不會影響到讀取的數據嗎?

      是的,大多數時候并不會影響到 IO 量,但是當我們還存在 order by 操作的時候,select 子句中的字段多少會在很大程度上影響到我們的排序效率,這一點可以通過我之前一篇介紹 MySQL ORDER BY 的實現分析的文章中有較為詳細的介紹。

      此外,上面誤區中不是也說了,只是大多數時候是不會影響到 IO 量,當我們的查詢結果僅僅只需要在索引中就能找到的時候,還是會極大減少 IO 量的。

      盡量用 join 代替子查詢

      雖然 Join 性能并不佳,但是和 MySQL 的子查詢比起來還是有非常大的性能優勢。MySQL 的子查詢執行計劃一直存在較大的問題,雖然這個問題已經存在多年,但是到目前已經發布的所有穩定版本中都普遍存在,一直沒有太大改善。雖然官方也在很早就承認這一問題,并且承諾盡快解決,但是至少到目前為止我們還沒有看到哪一個版本較好的解決了這一問題。

      盡量少 or

      當 where 子句中存在多個條件以“或”并存的時候,MySQL 的優化器并沒有很好的解決其執行計劃優化問題,再加上 MySQL 特有的 SQL 與 Storage 分層架構方式,造成了其性能比較低下,很多時候使用 union all 或者是union(必要的時候)的方式來代替“or”會得到更好的效果。

      盡量用 union all 代替 union

      union 和 union all 的差異主要是前者需要將兩個(或者多個)結果集合并后再進行唯一性過濾操作,這就會涉及到排序,增加大量的 CPU 運算,加大資源消耗及延遲。所以當我們可以確認不可能出現重復結果集或者不在乎重復結果集的時候,盡量使用 union all 而不是 union。

      盡量早過濾

      這一優化策略其實最常見于索引的優化設計中(將過濾性更好的字段放得更靠前)。

      在 SQL 編寫中同樣可以使用這一原則來優化一些 Join 的 SQL。比如我們在多個表進行分頁數據查詢的時候,我們最好是能夠在一個表上先過濾好數據分好頁,然后再用分好頁的結果集與另外的表 Join,這樣可以盡可能多的減少不必要的 IO 操作,大大節省 IO 操作所消耗的時間。

      避免類型轉換

      這里所說的“類型轉換”是指 where 子句中出現 column 字段的類型和傳入的參數類型不一致的時候發生的類型轉換:

      人為在column_name 上通過轉換函數進行轉換

      直接導致 MySQL(實際上其他數據庫也會有同樣的問題)無法使用索引,如果非要轉換,應該在傳入的參數上進行轉換

      由數據庫自己進行轉換

      如果我們傳入的數據類型和字段類型不一致,同時我們又沒有做任何類型轉換處理,MySQL 可能會自己對我們的數據進行類型轉換操作,也可能不進行處理而交由存儲引擎去處理,這樣一來,就會出現索引無法使用的情況而造成執行計劃問題。

      優先優化高并發的 SQL,而不是執行頻率低某些“大”SQL

      對于破壞性來說,高并發的 SQL 總是會比低頻率的來得大,因為高并發的 SQL 一旦出現問題,甚至不會給我們任何喘息的機會就會將系統壓跨。而對于一些雖然需要消耗大量 IO 而且響應很慢的 SQL,由于頻率低,即使遇到,最多就是讓整個系統響應慢一點,但至少可能撐一會兒,讓我們有緩沖的機會。

      從全局出發優化,而不是片面調整

      SQL 優化不能是單獨針對某一個進行,而應充分考慮系統中所有的 SQL,尤其是在通過調整索引優化 SQL 的執行計劃的時候,千萬不能顧此失彼,因小失大。

      盡可能對每一條運行在數據庫中的SQL進行 explain

      優化 SQL,需要做到心中有數,知道 SQL 的執行計劃才能判斷是否有優化余地,才能判斷是否存在執行計劃問題。在對數據庫中運行的 SQL 進行了一段時間的優化之后,很明顯的問題 SQL 可能已經很少了,大多都需要去發掘,這時候就需要進行大量的 explain 操作收集執行計劃,并判斷是否需要進行優化。

    bitsCN.com

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    MySQL數據庫性能優化之索引優化_MySQL

    MySQL數據庫性能優化之索引優化_MySQL:bitsCN.com 這篇文章是以 MySQL 為背景,很多內容同時適用于其他關系型數據庫,需要有一些索引知識為基礎 優化目標 減少 IO 次數 IO永遠是數據庫最容易瓶頸的地方,這是由數據庫的職責所決定的,大部分數據庫操作中超過90%的時間都是 IO 操作所占用的,
    推薦度:
    標簽: 副作用 數據 如何
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 国产伦精品一区二区三区| 精品亚洲成AV人在线观看| 久久99精品久久久久久久不卡 | 亚洲永久精品ww47| 欧美精品黑人巨大在线播放| 老司机午夜精品视频资源| 日韩视频中文字幕精品偷拍| 亚洲精品人成在线观看| 国产成人精品999在线观看| 亚洲国产精品无码久久SM| 久久久久99精品成人片三人毛片| 亚洲国产精品人久久| 98视频精品全部国产| 亚洲AV永久无码精品成人| 无码精品第一页| 久久久久国产精品三级网| 国产精品v欧美精品v日韩| 四虎精品成人免费永久| 国产精品视频免费| 2020亚洲男人天堂精品| 国产精品亚洲精品日韩已满| 日韩精品乱码AV一区二区| 亚洲午夜福利精品久久| 亚洲精品国产自在久久| 拍国产乱人伦偷精品视频| 久久精品视屏| 久久精品无码一区二区app| 精品无人区无码乱码大片国产| 国产精品九九久久免费视频 | 久久99精品免费一区二区| 国产精品无码免费专区午夜| 国产精品二区观看| 国产成人精品久久综合| 国产精品va久久久久久久| 国产精品区AV一区二区| 国产乱码精品一区二区三| 国产一区二区精品久久凹凸| 国产精品爽爽ⅴa在线观看| 久久精品国产99久久久| 久久婷婷国产综合精品| 亚洲精品二三区|