記一次mysql資料庫因字符集編碼導致索引失效的問題

2020-01-17     波波說運維

概述

今天開發反饋同樣的sql且數據量一致,但在綜測環境需要140多秒,而在開發環境只需要1秒多,這是什麼原因呢?下面一起來看看吧~


問題sql

SELECT ty.IS_FIXATION AS isFixation,CASE WHEN ty.INSPECTION_RULES IS NOT NULL  AND ty.IS_INSPECTION = 'Y' THEN '未打卡' ELSE NULL  END AS inspectionStatus,FROM t_ams_asset_card t LEFT JOIN T_AMS_ASSET_TYPE ty ON ty.TYPE_NO = t.ASSET_TYPE AND t.FINANCE_CODE = ty.ORG_CODELEFT JOIN hr_employee e ON t.USE_MAN = e.EMPLOYEE_CODEWHERE t.ASSET_MODULE = 'OWN'  AND t.IS_DELETE = 'N'

對比:

思路:這種情況一般是沒有索引或者索引失效導致。


1、對比執行計劃

這裡通過explain + sql查看執行計劃



2、檢查兩邊環境索引情況

可以發現兩邊環境都有索引,那應該就是某個索引失效了..



3、強制使用索引

這裡試一下 force index(HR_EMPLOYEE_U1) ,發現強制使用索引也是失效的,在這裡索引為什麼會失效呢?


4、檢查表存儲引擎、表欄位數據類型、表欄位字符集

一般索引失效都是表的存儲引擎、欄位數據類型或者字符集不同導致走的隱性轉換

show full columns from hr_employee;show full columns from t_ams_asset_card;



5、修改字符集編碼後測試

SELECTc.TABLE_SCHEMA '資料庫',c.TABLE_NAME '表',c.COLUMN_NAME '欄位',c.COLUMN_DEFAULT '默認值',c.IS_NULLABLE '是否為空',c.DATA_TYPE '欄位類型',c.character_set_name '原字符集',c.collation_name '原排序規則',CONCAT('ALTER TABLE ',TABLE_SCHEMA,'.',TABLE_NAME,' MODIFY COLUMN ',COLUMN_NAME,' ',COLUMN_TYPE,' CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ',CASEWHEN c.is_nullable = 'NO' THEN'NOT NULL' ELSE 'NULL' END,CASEWHEN c.COLUMN_DEFAULT = '' THEN' DEFAULT ''''' WHEN c.COLUMN_DEFAULT IS NULL THEN' DEFAULT NULL' ELSE concat( ' DEFAULT ', '''', c.COLUMN_DEFAULT, '''' ) END,' comment ','''',c.COLUMN_COMMENT,'''',';' ) '修正SQL' FROMinformation_schema.`COLUMNS` c WHEREtable_name = 'hr_employee' and table_schema='lcp_db'AND CHARACTER_SET_NAME = 'utf8';



6、再次查看執行計劃

調整後發現已使用索引,且sql執行也在1秒內,滿足需求。



覺得有用的朋友多幫忙轉發哦!後面會分享更多devops和DBA方面的內容,感興趣的朋友可以關注下~

文章來源: https://twgreatdaily.com/dyX2sG8B8wMrh2Li-0kD.html