MySql 高效能 5 5 維護索引和表

2021-08-21 06:33:28 字數 3046 閱讀 2426

維護表有三個主要目的:

1 找到並修復損壞的表

2 維護準確的索引統計資訊

3 減少碎片

5.5.1 找到並修復損壞的表

對於myisam 儲存引擎  ,表損壞通常是系統崩潰導致的。

其他引擎也會由於硬體問題 mysql本身的缺陷或者作業系統的問題導致。

innodb 引擎的表出現損壞,一定是出現了嚴重的錯誤。一般不會出現損壞,因為設計保證了它不容易出現損壞。

出現損壞的原因:

1 資料庫硬體問題,比如記憶體或者磁碟問題。

2 資料庫管理員的 誤操作,例如在mysq外部操作了資料檔案。

3 innodb本身缺陷。

常見的錯誤 比如嘗試使用rsync 備份innodb導致。不存在查詢能讓innodb表損壞,如果一條查詢導致innod表損壞,一定是遇到bug 而不是查詢問題。

損壞的索引會導致的問題:

1 查詢返回錯誤結果或者莫須有的主鍵衝突問題。

如何修復:

1 check table 檢查是否發生表損壞。(有些儲存引擎不支援該命令,有些通過其他的選項控制完全檢查表的方式)。check 通常能找到大多數的表和索引的錯誤。

2 repair table 來修復損壞的表,如果儲存引擎不支援和可以通過alter 操作來重建表。 

比如 針對innodb表 alter table innodb_1 engine=innodb;

3 使用離線工具 比如myisamchk 。

4 將資料匯出乙份然後重新匯入。

5 設定 innodb_force_recovery 引數進入innodb 強制恢復模式來修復資料。可以參考mysql 手冊。

6 使用開源的innodb 資料庫恢復工具 innodb data recovery toolkit 直接從innodb 資料檔案恢復資料。

如果損壞的系統區域或者而是表的行資料而不是索引,那麼就要從備份恢復表,或者嘗試從損壞的資料檔案中盡可能的恢復資料。

5.5.2  更新索引統計資訊

mysql 查詢優化器通過兩個api 了解儲存引擎的索引值分布資訊,用來決定如何使用索引。

records_in_range()  通過向儲存引擎傳入兩個邊界值獲取這個範圍大概有多少條記錄。myisam 返回精準值 innodb返回估算值。

info()  返回各種型別的資料,包括索引的基數,(每個鍵值有多少條記錄)

優化器根據儲存引擎返回的估算資料進行sql優化。如果表沒有統計資訊或者統計資訊不準確可能就是做出錯誤的決定。

各儲存引擎的統計資訊的支援:

1 memory 引擎不儲存索引統計資訊。

2 myisam 索引統計資訊儲存在磁碟上,analyze table  需要一次全索引掃瞄來計算索引基數,整個過程會鎖表。

3 innodb也不在磁碟儲存索引統計資訊,通過隨機索引訪問進行評估將資訊儲存在表中。

可以使用 show index from table 命令檢視索引的基數。cardinality 顯示儲存的估算索引列。 在mysql5.5 之後可以通過 information_schema.statistics表查詢這些資訊。

innodb 通過抽取樣本計算統計資訊,老版本樣本頁面是8 ,新版本通過 innodb_stats_samole_page 來設定樣本頁數。可以設定更大的值。生成更準確的索引資訊。

什麼時候生成統計資訊:

1 innodb 表會在首次開啟。

2 執行 analyze table 

3 表大小發生非常大的變化。表大小變化超過16分之1 或者新插入20億行資料 會觸發。

4 innodb 在開啟某些information_schema 表 或者show table status 和 show index 或者客戶端開啟自動補全功能的時候會觸發。

更新統計資訊可能會導致什麼問題:

1 導致大量的鎖。

2 啟動時間長。

可以關閉 innodb_stats_on_metadata 引數 來避免這些問題。

percona 版本 使用的是xtradb 引擎而不是 原生innodb引擎,可以通過innodb_staus_auto_update 引數禁止自動取樣。這樣就需要手動analuze table 更新統計資訊。可以用這個引數固化查詢計畫。

如果想要穩定的執行計畫,並在系統重啟後更快的生成統計資訊,可以使用系統表持久化這些表的統計資訊。

percona 5.1 和mysql 5.6 版本都加入這個特性 分別是 innodb_use_sys_stats_table和 innodb_analyze_is_persistent

5.5.3 減少索引和資料碎片

b tree 索引可能會碎片化,碎片的索引會以很差或者無序的方式存在磁碟上。

範圍掃瞄或者索引覆蓋掃瞄 速度都會降低。

表的資料儲存也可能碎片化,分為三種「

1 行碎片。資料行被儲存在多個地方的多個片段中。

2 行間碎片。邏輯上順序的頁或者行在磁碟上不是順序儲存。對全表掃瞄或者聚簇索引掃瞄有很大影響。本來可以順序掃瞄,現在就不行。

3 剩餘空間碎片。資料頁有大量的空餘空間,導致伺服器讀取大量不需要的資料。

mysiam 表 三種碎片都會存在,innodb不會出現短小行碎片,innodb會移動並重寫到乙個片段上。

如何整理資料:

1 optimize table 

2 匯出 匯入 整理資料

3 對於mysiam 可以通過排序演算法重建索引方式消除碎片

5 alter table  tablename  engine=; percona server 開啟了 expand_fast_index_creation 引數,可以同時消除表碎片和索引碎片。對於標準mysql版本只會消除表碎片(實際是聚簇索引) ,可以先刪除所有索引,然後重建表,最後重新建立索引的方式模擬percona server 的這個功能。

可以通過實際測量來確認是否需要消除索引和表的碎片,percona 的xtrabackup 有個--stats引數以非備份的方式執行,而只是列印索引和表的統計資訊,包括頁中的資料行,和空餘空間,來確定資料的碎片化程度,另外也要參考資料是否已經達到穩定程度,如果碎片化整理將表壓縮到一起可能反而導致後續的更新操作觸發一系列的頁**和重組,會對效能造成不良的影響。直到資料再次達到穩定。

mysql高效能索引 mysql高效能索引( )

在開發中,我們知道大多數應用的瓶頸在於sql語句的執行時耗,在這裡並不討論sql語句的安全,僅僅討論高效能sql語句,而與高效能sql語句緊密相連的就是傳說中的 索引。索引 一種工作在儲存引擎端的用於快速找到記錄的一種資料結構。mysql使用索引的方式是 先找到索引的值,再根據索引的值找到資料行。索...

高效能mysql(一) 建立高效能索引

單列索引和多列索引 單列索引 多個單列索引的選擇問題 多個or條件 多個單列的效能往往效能很低,盡量建立高效的多列索引。多列索引 選擇合適的索引順序 避免範圍條件 在where子句中,in是有效的,範圍條件會導致後面的索引無效!在order by中,範圍條件和in都會導致無法按照索引排序!按照索引順...

維護索引 通過重組索引提高效能

如果碎片程度小於30 建議使用重組而不是重建。因為重組不會鎖住資料頁或者資料表,並且降低cpu的資源。總得來說,重組會清空當前的b tree,特別是索引的葉子節點,重組資料頁和消除碎片。和重建不同,重組不會新增任何新資料頁。為了了解是否有必要重組索引,需要首先檢視碎片程度,如果在10 以下,那一般沒...