天天看點

RDS for MySQL 字元序(collation)引發的性能問題

本期分享專家:田傑,專注在關系型資料庫和nosql資料庫技術領域,曾先後就職于路透社和渣打銀行,目前在阿裡雲從事資料庫技術支援工作,号稱“資料庫問題的終結者”。

RDS for MySQL 字元序(collation)引發的性能問題

在幫客戶排查問題的時候,經常會遇到的 rds 執行個體性能問題(比如 rds 執行個體 cpu 使用率高),而其中有一類是由于字元集的字元排序規則不一緻導緻的。從處理的過程中可以看出來,這類問題比較容易出現但不容易定位排查,是以今天通過兩個實戰案例來分析的下“rds for mysql 字元序(collation)引發的性能問題”。

首先介紹下背景知識: 字元集 和 字元序。

1. 字元集(characte1 set)和字元序(collation)

字元集是一組符号和編碼,用來儲存和解釋 mysql 的字元類型資料,比如 varchar 類型的資料。

字元序是一組在指定字元集中進行字元比較的規則,比如是否忽略大小寫,是否按二進制比較字元等等。

兩組字元類型資料進行比較,需要一緻的字元集(character set)和 字元序(collation),否則需要進行隐式轉換。

<b>案例分析一:執行個體 cpu 使用率達到 100%,業務響應時間長,影響使用體驗。</b>

RDS for MySQL 字元序(collation)引發的性能問題

問題原因定位到一條普通查詢語句:

該語句在上線前通過 mysql 指令行進行過測試,執行時間在 20 ms(毫秒)左右。

但在生産環境由 php lavravel 架構送出執行需要 20 sec(秒)以上才可以完成; 大量該類型查詢執行導緻連接配接堆積,rds 執行個體 cpu 使用率 100%。

首先在 mysql 指令行下,檢查表結構:

檢查執行計劃,未見異常:

RDS for MySQL 字元序(collation)引發的性能問題

請使用者協助捕捉 php laravel 架構送出查詢的網絡通信過程:

RDS for MySQL 字元序(collation)引發的性能問題

在網絡互動過程中,發現應用在連接配接建立後執行了下面的語句,然後間隔部分其他查詢後才執行的上述查詢:

那麼這條指令具體修改了什麼,可以通過 mysql 指令行連接配接來模拟驗證下 :

RDS for MySQL 字元序(collation)引發的性能問題

可以看到,該條指令将連接配接的字元序(collation_connection)從 utf8_general_ci (預設值)修改為 utf8_unicode_ci ;而表中資料使用的是預設字元序(utf8_general_ci,在表的 create 定義語句中如果沒有指定,則使用字元集的預設字元序),兩者并不相同。

注:

    rds for mysql 支援的字元序可以通過下面的指令擷取:

RDS for MySQL 字元序(collation)引發的性能問題

在修改了字元序後,語句的執行計劃就變為全索引掃描:

RDS for MySQL 字元序(collation)引發的性能問題

請注意查詢的執行成本由 8427 改變為 13771569,增加了 1633 倍。

修改架構的字元序設定後,查詢執行時間恢複正常,rds 執行個體 cpu 使用率過高的問題解決。

<b></b>

<b>案例分析二:rds 執行個體 cpu 使用率波動性打高,導緻業務卡頓。</b>

RDS for MySQL 字元序(collation)引發的性能問題

定位到下面的查詢,檢查語句執行計劃,發現優化器對表 tab03 選擇了全表掃描的方式來通路資料。

而表 tab03 上有合适的唯一索引 r_cp_tab03_uk:

而且 extra 字段給出的是 range checked for each record(index map:0xa),說明存在潛在可以使用的索引,但由于某種原因無法使用。

檢視表 tab02 的定義:

表 tab02 的 cp_no 字段采用 utf8_bin(按二進制比較,不忽略大小寫) 字元序,而表 <b>tab03 </b>的 cp_no 字段采用 utf8_general_ci(預設)字元序,兩者字元序不比對,是以無法使用正确的索引。

修改表 <b>tab03 </b>的 cp_no 字段字元序為 utf8_bin,執行計劃恢複正常,rds 執行個體 cpu 波動性打高的問題解決。

RDS for MySQL 字元序(collation)引發的性能問題

<b>從以上的案例可以看到,正确的執行計劃相較調整前的執行計劃效率大約提升了 13221 倍。</b><b>字元序不僅僅可以導緻 cpu 使用率問題,也可能引入比如 iops 使用率高 等其他問題。</b><b>是以建議應用開發保持統一的字元集和字元序使用規範,避免規範不統一引入性能問題。</b>

<b>本期分享就到這裡了,歡迎大家留言讨論有關的資料庫的問題,我們年後再見,在此祝大家新年快樂,雞年大吉!</b>