1.索引創建注意事項
適合的場景
1.頻繁使用where語句查詢的字段
2.關聯字段需要建立索
3.如果不創建索引,那么在連接的過程中,每個值都會進行一次全表掃描
4.分組和排序字段可以建立索引因為索引天生就是有序的,在分組和排序時優勢不言而喻
5.需要進行聚合統計的字段可以創建索引
6.比如需要對school字段進行count0操作:因
為B+樹相同的值都存儲在同一個葉子節點中統計速度很快但是并不是所有上訴的字段都可以建立索引,還需要考慮他是否是一下情況
不適合的場景
1.字段頻繁的更新 因為頻繁的更新除了修改表數據外還需要維護索引信息,B+樹調整會降低性能
2.字段取值重復率高,區分度低唯一性差的字段不適合創建索引
3.比如性別字段,取值過于
·參與列計算的列不適合創建索引,索引會失效
2.MySQL中的索引數量是否越多越好?為什么?
因為索引不論從時間還是空間上都是有一定成本的
1)時間
每次對表中的數據進行增刪改(NSERT、UPDATE或DELETE)的時候,索引也必須被更新,這會增加寫入操作的開銷。例如刪除了一個name為面試鴨的記錄,不僅主鍵索引上需要修改,如果name字段有索引,那么name索引也需要修改,所以索引越多需要?改的地方也就越多,時間開銷就大了,并且B+樹可能會有頁分裂、合并等操作,時間開銷就會更大。
還有一點需要注意:小ySQL有個查詢優化器,它需要分析當前的查詢,選擇最優的計劃,這過程就需要考慮選擇明那個索引的查詢成本低。如果索引過多,那么會導致優化器耗費更多的時間在選擇上,甚至可能因為數據的不準確而選擇了次優的索引。
2)空間
每建立一個二級索引,都需要新建一個B+樹,默認每個數據頁都是16KB,如果數據量很大,索引又很多,占用的空間可不小。
3.MySQL中如何進行SQL調優?
1.避免select*,只查詢必要的字段
2.合理設計索引,通過聯合索引進行覆蓋索引及索引下推技術的優化,減少回表的次數,提升效率
3.避免SQL中進行函數計算等操作,導致無法命中索引
4.避免使用like,導致全表掃描(如果符合最左前綴匹配原則可以走索引)】
5.注意使用聯合索引需滿足最左匹配原則
6.不要對無索引字段進行排序操作
7.連表查詢需注意不同字段的字符集保持一致
8.注意隱式類型轉換操作,會導致索引失效使用OR,兩邊需保持等值匹配且都為索引列,才會走索引
以上都是對SQL進行優化,避免索引失效等進行SQL調優,還可以從其他方面進行考慮,比如先分析SQL慢的原因
-索引失效
-多表oin
-查詢字段太多
-表中數據量太大
-索引區分度不高
-數據庫連接數不夠
-數據庫的表結構不合理
-數據庫IO或者CPU比較高
-數據庫參數不合理
-長事務導致的
-鎖競爭導致的長時間的等待
拓展:
1:為什么多表join會導致SQL慢?
MySQL是使用了嵌套循環(Nested.-Loop Join)】的方式來實現關聯查詢的,簡單點說就是要通過兩層循環,用第一張表做外循環,第二張表做內循環,外循環的每一條記錄跟內循環中的記錄作比較,符合條件的就輸出。而具體到算法實現上主要有simple nested loopblock nested loop和index nested loop這三種。而且這三種的效率都沒有特別高。小ySQL是使用了嵌套循環(Nested-Loop Join)的方式來實現關聯查詢的,如果有2張表join的話,復雜度最高是0(n2),3張表則足0n3)隨著表越多,表中的數據量越多,JOIN的效率會呈指數級下降。
2:不使用引oin,如何做關聯查詢?
主要有以下做法
1、在內存中自己做關聯,即先從數據庫中把數據查出來之后,我們在代碼中再進行二次查詢,然后再進行關聯。
2、數據冗余,那就是把一些重要的數據在表中做冗余,這樣就可以避免關聯查詢了。
3、寬表,就是基于一定的join關系,把數據庫中多張表的數據打平做一張大寬表,可以同步到ES或者干脆直接在數據庫中直接查都可以
3.數據量太大也會導致SQL慢,那怎么解決?
具體的解決方案有以下幾種:
1、數據歸檔,把歷史數據移出去,比如只保留最近半年的數據,半年前的數據做歸檔。
2、分庫分表、分區。把數據拆分開,分散到多個地方去,這里不詳細介紹了,我們的文檔中有分庫分表和分區的詳細介紹,不展開了。
3、使用第三方的數據庫,比如把數據同步到支持大數量查詢的分布式數據庫中,如oceanbase、