Java八股文之MySQL優化相關面試題

字號+ 編輯: 种花家 修訂: 种花家 來源: 网络转载 2024-06-20 我要說兩句(0)

當然有的大佬喜歡刷leetcode,背誦網上的一些八股文對面試也沒壞處。

面試專用——

MySQL調優篇

高性能的索引使用策略

1. 不在索引列上做任何操作

2. 盡量全值匹配,建立了聯合索引列後,如果我們的搜索條件中的列和索引列一致的話,這種情況就稱爲全值匹配

3. 最佳左前綴法則。在我們的搜索語句中也可以不用包含全部聯合索引中的列,但要遵守最左前綴法則。指的是查詢從索引的最左前列開始並且不跳過索引中的列。搜索條件中必須出現左邊的列才可以使用到這個B+樹索引

4. 範圍條件放最後,對於一個聯合索引來說,雖然對多個列都進行範圍查找時只能用到最左邊那個索引列,但是如果左邊的列是精確查找,則右邊的列可以進行範圍查找。

5. 覆蓋索引盡量用。索引條目通常遠小於數據行大小,所以如果只需要讀取索引,那 MySQL就會極大地減少數據訪問量。這對緩存的負載非常重要,因爲這種情況下響應時間大部分花費在數據拷貝上。覆蓋索引對於I/O密集型的應用也有幫助,因爲索引比數據更小,更容易全部放入内存中。

6. 不等於要慎用,mysql 在使用不等於(!= 或者<>)的時候無法使用索引會導致全表掃描

7. 需要注意null/not null對索引的可能影響。對於 is not null直接走的全表掃描。

8. Like查詢要當心。like以通配符開頭('%abc...'),mysql索引失效會變成全表掃描的操作。

此時如果使用覆蓋索引可以改善這個問題。

9. 字符類型加引號,字符串不加單引號索引失效。

10. 使用or關鍵字時要注意,or是不同列,並且order_note不是索引。所以只能全表掃描

11. 使用索引掃描來做排序和分組

MySQL有兩種方式可以生成有序的結果﹔通過排序操作﹔或者按索引順序掃描施﹔如果EXPLAIN出來的type列的值爲“index”,則說明MySQL使用了索引掃描來做排序。

掃描索引本身是很快的,因爲只需要從一條索引記錄移動到緊接著的下一條記錄。但如果索引不能覆蓋查詢所需的全部列,那就不得不每掃描一條索引記錄就都回表查詢一次對應的行。這基本上都是隨機I/O,因此按索引順序讀取數據的速度通常要比順序地全表掃描慢,尤其是在IO密集型的工作負載時。

MySQL可以使用同一個索引既滿足排序,又用於查找行。因此,如果可能,設計索引時應該盡可能地同時滿足這兩種任務,這樣是最好的。

只有當索引的列順序和ORDER BY子句的順序完全一致,並且所有列的排序方向(倒序或正序)都一樣時,MySQL才能夠使用索引來對結果做排序。如果查詢需要關聯多張表,則只有當0RDER BY子句引用的字段全部爲第一個表時,才能使用索引做排序。

12. ASC、DESC別混用

對於使用聯合索引進行排序的場景,我們要求各個排序列的排序順序是一致的,也就是要麽各個列都是ASC槼則排序,否則應都用DESC槼則排序

13. 盡可能按主鍵順序插入行

14. 優化Count查詢,COUNT()都需要掃描大量的行(意味著要訪問大量數據)才能獲得精確的結果,因此是很難優化的。在MySQL層面能做的基本只有索引覆蓋掃描了。如果這還不夠,就需要考慮修改應用的架構,可以用估算值取代精確值,可以增加滙總表,或者增加類似Redis這樣的外部緩存系統

15. 優化limit分頁

在系統中需要進行分頁操作的時候,我們通常會使用LIMIT加上偏移量的辦法實現,同時加上合適的ORDER BY子句。一個非常常見又令人頭疼的問題就是,在偏移量非常大的時候

優化此類分頁查詢的一個最簡單的辦法是

會先查詢翻頁中需要的N條數據的主鍵值,然後根據主鍵值回表查詢所需要的N條數據,在此過程中查詢N條數據的主鍵id在索引中完成,所以效率會高一些。

高性能索引的創建策略

索引列的類型盡量小

這個建議對於表的主鍵來說更加適用,因爲不僅是聚簇索引中會存儲主鍵值,其他所有的二級索引的節點處都會存儲一份記錄的主鍵值,如果主鍵適用更小的數據類型,也就意味著節省更多的存儲空間和更高效的I/0。

索引的選擇性

創建索引應該選擇選擇性/離散性高的列。索引的選擇性/離散性是指,不重複的索引值(也稱爲基數,cardinality)和數據表的記錄總數(N)的比值,範圍從1/N到1之間。索引的選擇性越高則查詢效率越高,因爲選擇性高的索引可以讓MySQL在查找時過濾掉更多的行。唯一索引的選擇性是1,這是最好的索引選擇性,性能也是最好的。

前綴索引

針對blob、text、很長的varchar字段,mysql不支持索引他們的全部長度,需建立前綴索引。

語法:Alter table tableName add key/index (column(X))

缺點:前綴索引是一種能使索引更小、更快的有效辦法,但另一方面也有其缺點MySQL無法使用前綴索引做ORDER BY和GROUP BY,也無法使用前綴索引做覆蓋掃描。

有時候後綴索引 (suffix index)也有用途(例如,找到某個域名的所有電子郵件地址)。MySQL原生並不支持反向索引,但是可以把字符串反轉後存儲,並基於此建立前綴索引。可以通過觸發器或者應用程序自行處理來維護索引。

只爲用於搜索、排序或分組的列創建索引

只爲出現在WHERE 子句中的列、連接子句中的連接列創建索引,而出現在查詢列表中的列一般就沒必要建立索引了,除非是需要使用覆蓋索引;又或者爲出現在ORDER BY或GROUP BY子句中的列創建索引

多列索引

多列索引的列順序至關重要。對於如何選擇索引的列順序有一個經驗法則:將選擇性最高的列放到索引最前列。當不需要考慮排序和分組時,將選擇性最高的列放在前面通常是很好的。這時候索引的作用只是用於優化WHERE條件的查找。在這種情況下,這樣設計的索引確實能夠最快地過濾出需要的行,對於在WHERE子句中只使用了索引部分前綴列的查詢來說選擇性也更高。

然而,性能不只是依賴於索引列的選擇性,也和查詢條件的有關。可能需要根據那些運行頻率最高的查詢來調整索引列的順序,比如排序和分組,讓這種情況下索引的選擇性最高。

同時,在優化性能的時候,可能需要使用相同的列但順序不同的索引來滿足不同類型的查詢需求。

三星索引

一星:

一星的意思就是:如果一個查詢相關的索引行是相鄰的或者至少相距足夠靠近的話,必須掃描的索引片寬度就會縮至最短,也就是說,讓索引片盡量變窄,也就是我們所說的索引的掃描範圍越小越好。

二星(排序星) :

在滿足一星的情況下,當查詢需要排序,group by、 order by,如果查詢所需的順序與索引是一致的(索引本身是有序的),是不是就可以不用再另外排序了,一般來說排序可是影響性能的關鍵因素。

三星(寬索引星) :

在滿足了二星的情況下,如果索引中所包含了這個查詢所需的所有列(包括 where 子句和 select 子句中所需的列,也就是覆蓋索引),這樣一來,查詢就不再需要回表了,減少了查詢的步驟和IO請求次數,性能幾乎可以提升一倍。

MySQL的調優(熟悉業務的)

架構調優

在系統設計時首先需要充分考慮業務的實際情況,是否可以把不適合數據庫做的事情放到數據倉庫、搜索引擎或者緩存中去做;然後考慮寫的並發量有多大,是否需要採用分布式;最後考慮讀的壓力是否很大,是否需要讀寫分離。對於核心應用或者金融類的應用,需要額外考慮數據安全因素,數據是否不允許丟失。所以在進行優化時,首先需要關注和優化的應該是架構,如果架構不合理,即使是DBA能做的事情其實是也是比較有限的。

MySQL調優

需要確認業務表結構設計是否合理,SQL語句優化是否足夠,該添加的索引是否都添加了,是否可以剔除多餘的索引等等

硬件和OS調優

需要對硬件和OS有著非常深刻的了解,僅僅就磁盤一項來說,一般非DBA能想到的調整就是固態硬盤比用機械硬盤更好。DBA級別考慮的至少包括了,使用什麽樣的磁盤陣列(RAID)級別、是否可以分散磁盤IO、是否使用裸設備存放數據,使用哪種文档系統(目前比較推薦的是XFS),操作系統的磁盤調度算法選擇,是否需要調整操作系統文档管理方面比如atime屬性等等。

查詢性能優化

慢查詢(核心原因查詢數據量太多了,減少訪問的數據量)

查詢花費大量時間的日志,是指mysql記錄所有執行超過long_query_time參數設定的時間閾值的SQL語句的日志。該日志能爲SQL語句的優化帶來很好的幫助。默認情況下,慢查詢日志是關閉的,要使用慢查詢日志功能,首先要開啓慢查詢日志功能。。

1.確認應用程序是否在檢索大量超過需要的數據。這通常意味著訪問了太多的行,但有時候也可能是訪問了太多的列。

2.確認MySQL服務器層是否在分析大量超過需要的數據行。

l slow_query_log 啓動停止慢查詢日志

l slow_query_log_file 指定慢查詢日志得存儲路徑及文档(默認和數據文档放一起)

l long_query_time 指定記錄慢查詢日志SQL執行時間得伐值(單位:秒,默認10秒)

l log_queries_not_using_indexes 是否記錄未使用索引的SQL

l log_output 日志存放的地方可以是TABLE[FILE,TABLE]

 

閲完此文,您的感想如何?
  • 有用

    142

  • 沒用

    98

  • 開心

    13

  • 憤怒

    29

  • 可憐

    45

1.如文章侵犯了您的版權,請發郵件通知本站,該文章將在24小時内刪除;
2.本站標注原創的文章,轉發時煩請注明來源;
3.交流群: 2702237 13835667

相關課文
  • mac開發接入微信公衆號接口返回報錯 cURL error 56: SSLRead() return error -9806

  • pecl安裝程序時報錯Array and string offset access syntax with curly braces is no longer supported

  • PHP的換行符是什麽

  • 由於商家傳入的H5交易參數有誤,該筆交易暫時無法完成,請聯繫商家解決

我要說說
網上賓友點評