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

日活3kw下,如何應對實際業務場景中SQL過慢的優化挑戰?

數據庫 其他數據庫
type=index 意味著進行了全索引掃描, 會遍歷索引樹來查找匹配的行,這個效率比掃表掃描快一些,但是很有限,和我們通常意義上理解的走了索引 是兩回事兒。

在面試中,SQL調優是一個常見的問題,通過這個問題可以考察應聘者對于提升SQL性能的理解和掌握程度。通常來說,SQL調優需要按照以下步驟展開。

首先,需要發現問題。最好結合具體業務情況,比如某次線下報警顯示出現了慢SQL,或者接口響應時間較長,經過性能分析發現問題出現在SQL查詢上。無論何種情況,都要有一個背景故事。

一旦問題被確定,就需要進行問題分析了。

接著首先要定位具體的SQL語句,這可以通過各種監控工具或平臺來實現。一旦定位到SQL語句,就能知道是哪張表、哪個SQL語句在拖慢性能。

接下來就是進行分析了。一般來說,一個SQL查詢變慢可能有以下幾個原因:

  1. 索引失效
  2. 多表連接
  3. 查詢字段過多
  4. 數據量過大
  5. 索引字段基數太小
  6. 數據庫連接不足
  7. 數據庫表結構不合理
  8. 數據庫IO或CPU負載高
  9. 數據庫參數設置不合理
  10. 長時間事務
  11. 鎖競爭導致的等待

因此,進行完整的SQL調優通常需要考慮以上因素中的一個或多個。在優化過程中,會逐個解決這些問題。

情況一:索引失效

首先,當遇到索引失效的問題時,我們通常會通過執行計劃來分析數據庫查詢是否有效地利用了索引。執行計劃可以告訴我們查詢是如何執行的,是否使用了索引以及索引的效率如何。如果發現查詢沒有使用索引或者索引效率低下,可能是因為索引設計不合理或者數據分布不均勻導致索引失效。在這種情況下,我們可以考慮優化索引設計,重新構建索引,或者調整SQL查詢語句以更好地利用索引。有時候,我們也可以通過強制指定特定的索引來引導查詢優化器選擇正確的索引。除了修改索引和SQL語句,還可以考慮優化查詢條件,避免使用通配符開頭的LIKE語句,盡量避免在WHERE子句中對字段進行函數操作,以及盡量減少JOIN操作的復雜度。這些方法都可以幫助提高查詢性能和優化索引使用。如果遇到索引失效問題,還可以考慮使用數據庫提供的工具和分析功能來進一步診斷和解決問題。

特殊情況-Explain 執行計劃中,key有值,還是很慢怎么辦?

這是在實際中遇到的一種情況。我相信大家或多或少也是遇到過這種情況的。

在執行計劃中,當看到key字段有值且type為index時,很多人錯誤地認為這表示查詢已經利用了索引。當我們查看一個SQL查詢的執行計劃時,經常會遇到類似以下的情況:

id

select_type

table

type

possible_keys

key

key_len

ref

rows

Extra

1

SIMPLE

users

index

NULL

email_index

767

const

1

Using where; Using index

這個執行計劃中,type=index,key=email_index 很多人會認為這表示這條SQL走了索引,但是其實這么理解是不對的。

如果是走了索引Extra中的內容應該是Using index 而不是Using where; Using index

以上的這個執行計劃表明,這個SQL確實用到了email_index的這個索引樹,但是他并沒有直接通過索引進行匹配或者范圍查詢,而是掃描了整顆索引樹。

所以,type=index 意味著進行了全索引掃描, 會遍歷索引樹來查找匹配的行,這個效率比掃表掃描快一些,但是很有限,和我們通常意義上理解的走了索引 是兩回事兒。

遇到這種情況,大概率是因為沒有遵守最左前綴匹配導致的索引失效了。所以需要調整查詢語句,或者修改索引來解決。

情況二:多表JOIN

在SQL查詢中,多表連接是導致執行速度變慢的常見原因之一。當我們需要從多個表中檢索數據并將它們組合在一起時,就會使用多表連接。然而,如果不加以優化,這種連接可能會導致查詢性能下降。

多表連接的執行速度變慢主要是因為數據庫系統需要同時處理多個表,進行數據匹配和組合。這可能涉及大量的數據掃描、比較和排序,導致查詢變得緩慢。

為了解決多表連接導致的性能問題,我們可以采取一些優化措施:

  1. 優化查詢條件:確保在連接表時使用有效的查詢條件,限制返回的數據量。這可以減少不必要的數據匹配,提高查詢效率。
  2. 合理使用索引:為連接字段創建索引,這樣可以加快數據匹配的速度。索引可以幫助數據庫系統快速定位需要匹配的數據。
  3. 限制返回字段:只選擇需要的字段,避免返回過多的數據。減少返回字段的數量可以降低數據傳輸和處理的負擔。
  4. 考慮表的大小和結構:在設計數據庫表結構時,考慮到表的大小和關系,可以更好地優化多表連接的性能。
  5. 使用適當的連接類型:根據查詢需求選擇合適的連接類型,如INNER JOIN、LEFT JOIN、RIGHT JOIN等。不同的連接類型會影響查詢的結果和性能。

舉個例子,假設我們有兩個表:users和orders,我們想要查詢用戶及其對應的訂單信息。如果我們使用以下SQL查詢:

SELECT users.name, orders.order_id
FROM users
JOIN orders ON users.user_id = orders.user_id;

在這個查詢中,我們通過user_id字段將users表和orders表連接起來,但如果這兩個表的數據量很大,且沒有合適的索引,查詢可能會變得很慢。通過優化查詢條件、添加索引、限制返回字段等方式,可以改善這個查詢的性能,使其執行更加高效。

為什么互聯網公司都不建議使用多表join?

在SQL查詢中,使用JOIN操作可能會導致效率較低的主要原因在于其實現方式

MySQL通常使用嵌套循環(Nested-Loop Join)來執行關聯查詢。簡單來說,這意味著要通過兩層循環來比較兩個表的記錄,外循環遍歷第一個表,內循環遍歷第二個表,然后逐條比較記錄,符合條件的結果被輸出。

具體到算法實現上,MySQL主要采用了三種方式:簡單嵌套循環(Simple Nested Loop)、塊嵌套循環(Block Nested Loop)和索引嵌套循環(Index Nested Loop)。然而,這三種方式的效率都不是特別高。

在實際應用中,如果有兩個表進行JOIN操作,復雜度最高可以達到O(n^2),而對于三個表則是O(n^3),隨著表的數量和數據量的增加,JOIN操作的效率會呈指數級下降。

值得一提的是,在MySQL 8.0中引入了哈希連接(Hash Join)算法,這種算法可以提高JOIN操作的效率。哈希連接通過構建哈希表來快速查找匹配的記錄,相比于嵌套循環,可以更有效地處理JOIN操作,提升查詢性能。

因此,盡管JOIN操作在處理多表關聯查詢時很常見,但需要注意其效率問題。為了優化查詢性能,可以考慮使用適當的索引、優化查詢條件、限制返回字段數量,以及利用新的算法如哈希連接來改善JOIN操作的效率。

關于什么是Hash Join ,感興趣的話后期可以單獨出一期文章單獨說明一下。

情況三:索引基數太小不合理

  • 什么時字段基數?

舉個例子,有一個字段它一共在10萬行數據里有10萬個值對吧?結果呢?這個10萬值,要不然就是0,要不然就是1,那么他的基數就是2,為什么?因為這個字段的值就倆選擇,0和1。假設你要是針對上面說的這種字段建立索引的話,那就還不如全表掃描了,因為你的索引樹里就僅僅包含0和1兩種值,根本沒法進行快速的二分查找,也根本就沒有太大的意義了,所以這種時候,選用這種基數很低的字段放索引里意義就不大了。

情況四:查詢字段太多

在數據庫查詢中,查詢字段過多通常是因為我們錯誤地使用了SELECT *,導致返回了所有字段的數據。一般來說,如果查詢字段少于100個,通常不會造成太大問題,除非字段數量非常龐大。在這種情況下,我們可以采取兩種方法來解決。

首先,避免查詢那些不必要的字段,只選擇需要的少部分字段進行查詢。這樣可以減少數據傳輸和處理的負擔,提高查詢效率。

其次,可以考慮進行分表,即垂直分表,將數據拆分到多個表中。通過這種方式,可以將數據分散存儲在不同的表中,降低單張表的數據量,提升查詢性能。然而,需要注意的是,分表可能會引入多表JOIN的問題,因此在進行拆分時需要考慮數據冗余的情況。

所以,對于查詢字段過多的情況,除了避免不必要字段的查詢外,還可以考慮通過垂直分表的方式來優化數據存儲和查詢性能。在拆分表時,需謹慎考慮數據冗余和可能引發的多表JOIN問題,以達到更高效的數據查詢和處理。

情況五:表中數據量太大

當單個表中的數據量超過1000萬條時,通常會導致查詢效率下降,即使使用了索引也可能變得比較緩慢。在這種情況下,單純建立索引并不能完全解決問題。因此,針對大數據量表的情況,可以考慮以下幾種解決方案:

  1. 數據歸檔:將歷史數據移出主表,保留只保留最近半年的數據,而將半年前的數據進行歸檔。這樣可以減少單表數據量,提升查詢效率。
  2. 分庫分表、分區:將數據拆分到多個庫、多個表或者進行分區存儲。通過分散數據存儲的方式,可以有效降低單表數據量,提高查詢性能。關于分庫分表和分區的詳細介紹可以在相關文檔中查閱。
  3. 使用第三方數據庫:將數據同步到支持大規模查詢的分布式數據庫中,例如OceanBase、TiDB,或者存儲到搜索引擎中,如Elasticsearch等。這些數據庫具有更好的擴展性和處理大數據量的能力,可以提升查詢效率和系統性能。

所以,針對表中數據量過大的情況,除了建立索引外,還可以通過數據歸檔、分庫分表、分區和使用第三方數據庫等方式來優化數據存儲和查詢性能,以應對大數據量帶來的查詢效率問題。

情況六:數據庫連接數不夠

當數據庫連接數不足時,需要具體分析造成這種情況的原因。可能的原因有幾個:

  1. 業務量過大:如果業務量巨大,單個數據庫無法承載,那么最好的解決方案是進行數據庫分庫操作,將數據分散存儲在多個庫中,以減輕單庫壓力。
  2. 慢SQL或長事務:存在一些慢SQL查詢或長時間運行的事務,會占用數據庫連接資源,導致數據庫連接數不足。這種情況下,慢SQL會占用連接資源,導致其他查詢被阻塞,進而影響整體查詢效率。

其實這種情況如果系統的用戶較多,其實很是較容易遇到的。比如:之前我就遇到過類似的問題,報錯如下:

Caused by: ERR-CODE: [TDDL-4103][ERR_ATOM_CONNECTION_POOL_FULL] 
Pool of DB 'cn-zhxxx_i-xxx_fin_risk_xxx_30xx:33.10.xxx.xx:30xx' is full. 
Message from pool: wait millis 5000, active 10, maxActive 10. 
AppName:FIN_RISK_xxx_APP, Env:ONLINE, UnitName:null.

如果發現上述問題,則需要去監平臺上看一下相關SQL的耗時情況

我們的問題其實就是簡單的一個更新語句,其中使用了樂觀鎖進行并發控制。

為什么樂觀鎖還會導致大量的鎖耗時呢?

雖然樂觀鎖是不需要加鎖的,通過CAS的方式進行無鎖并發控制進行更新的。但是InnoDB的update語句是要加鎖的。當并發沖突比較大,發生熱點更新的時候,多個update語句就會排隊獲取鎖。

而這個排隊的過程就會占用數據庫鏈接,一旦排隊的事務比較多的時候,就會導致數據庫連接被耗盡。

當數據庫連接被耗盡時,通常是因為排隊的事務過多導致的。在高并發情況下,如果排隊的事務數量很大,就會耗盡數據庫連接資源。

這類問題的解決思路有以下幾個:

  1. 使用緩存進行熱點數據更新,如Redis,以減輕數據庫壓力。
  2. 采用異步更新的方式,平滑處理高并發更新請求,避免峰值沖擊。
  3. 將熱點數據拆分存儲到不同的庫或表中,減少并發沖突。
  4. 合并更新請求,通過批量執行的方式降低沖突。例如,將多個增加積分的操作合并為一次性批量執行,減少數據庫負擔。

需要注意的是,第2和第4種方案會引入一定的延遲,將實時更新變為異步更新,可能會影響數據的實時性。而第1和第3種方案在實施過程中成本較高,但相對更完整。

根據實際業務場景,選擇合適的解決方案非常重要。在某些情況下,如我們的業務場景,選擇第4種方案,即合并更新操作并批量執行,可以有效降低數據庫連接壓力。舉例來說,如果需要給100個用戶增加積分,可以將這些操作合并并在一定時間間隔內批量執行,以減少數據庫負擔。

情況七:數據庫表結構不合理

當數據庫表結構不合理時,這也是造成性能問題的關鍵原因之一。例如,某些字段存儲了過長的內容,或者缺乏合理的冗余導致需要頻繁進行多表關聯查詢。解決這類問題的思路通常是進行數據庫重構或者考慮分表操作。

情況八:數據庫IO或者CPU比較高

另外,數據庫高IO或CPU占用率也是常見的問題。當數據庫整體IO或CPU負載過高時,查詢速度可能會下降,因此需要分析背后的原因并采取相應的解決方案。

情況九:存在長事務

長事務和慢SQL問題類似,都會占用數據庫連接,導致其他請求需要等待。

情況十:鎖競爭導致的等待

在數據庫中,鎖競爭也會導致等待。當多個并發請求爭奪共享資源時,會導致鎖等待,進而增加執行時間,使SQL變慢。這種情況也會類似于CPU被打滿的問題。

情況十一:數據庫參數不合理

針對具體業務場景,適當調整數據庫參數可以顯著提升SQL效率。例如,調整內存大小、緩存大小、線程池大小等參數都可能對數據庫性能產生影響。

責任編輯:武曉燕 來源: 碼上遇見你
相關推薦

2024-03-11 15:13:22

數據庫高并發

2022-10-14 17:24:35

MySQLSQL優化

2012-05-09 10:24:50

WAN優化器VDI

2020-08-04 10:49:26

云遷移云計算云平臺

2009-01-20 10:51:55

Oracle政府行業信息化

2009-09-24 16:56:12

2022-07-13 16:54:48

邊緣計算物聯網大數據

2020-02-06 09:37:18

云計算工具技術

2017-07-20 15:05:55

新浪微博極端峰值

2019-12-23 10:47:54

ICS安全物聯網安全物聯網

2022-10-09 10:11:06

物聯網安全網絡攻擊

2024-05-15 08:00:00

DevOps平臺工程

2017-12-02 21:33:43

2024-06-19 09:34:38

系統數據庫內存

2012-09-04 13:58:50

存儲海量存儲華為

2011-08-29 14:33:41

2020-08-21 10:58:43

云計算云安全技術

2021-01-25 09:00:00

機器學習人工智能算法

2014-01-08 13:43:26

迪普CGN中電信

2024-12-17 14:16:39

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文日韩在线 | 日韩欧美国产一区二区 | 青青草在线播放 | www.成人久久 | 九九视频在线观看 | 亚洲日本免费 | 毛片黄片| 国产精品99久久久久久久久久久久 | 91视频进入 | 在线免费观看成年人视频 | 国产精品久久久久国产a级 欧美日本韩国一区二区 | www.久久久.com| 国产精品大全 | 一区二区三区四区视频 | 久久久久久国产一区二区三区 | 日本不卡在线视频 | 亚洲国产精品久久久 | 黄色网页在线观看 | 久久精品国产清自在天天线 | 亚洲精品自在在线观看 | 亚洲精品一区二三区不卡 | 亚洲精品日韩一区二区电影 | 成人二区 | 一区二区三区在线免费 | 日韩在线| 日韩免费看视频 | 欧美日韩在线播放 | 日本免费在线看 | 最新日韩精品 | 国产观看| 国产精品久久久久久久久久久久午夜片 | 亚洲欧美精 | 欧美黄页| jⅰzz亚洲| 成人激情视频在线观看 | 久久久久无码国产精品一区 | 中文字幕亚洲欧美日韩在线不卡 | 色吊丝2288sds中文字幕 | 粉嫩一区二区三区国产精品 | 在线免费黄色小视频 | 日韩中文字幕区 |