這個SQL你會最佳化嗎?

資料庫工作筆記發表於2023-12-28

來源:DBA札記

1背景

昨天晚上某群友問我一個SQL最佳化問題,我當時在處理公司問題,就讓他丟到群裡大家看。經過大家“我來找茬”,最終問題得以解決。廢話到這裡,上菜。

2問題SQL

SELECT *
FROM table1 t1
WHERE t1.number IN (
 SELECT batch_no
 FROM table2 
 WHERE id = '260002'
);

表結構 t1

CREATE TABLE `table1` (
  `id` varchar(38) NOT NULL COMMENT 'id',
  `number` varchar(50) NOT NULL COMMENT '調整後交易批號',
  PRIMARY KEY (`id`),
  KEY `idx1` (`number`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='交易單明細';

表結構 t2

CREATE TABLE `table2` (
 `id` varchar(38) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'id',
 `batch_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '結算批號',
 PRIMARY KEY (`id`),
 KEY `idx1` (`batch_no`),
) ENGINE = InnoDB CHARSET = utf8mb3 COMMENT '結算單';

3現象

針對問題SQL,加force index, 各種改寫,都沒法走索引,表資料大概有300w,所以還是有點影響。

4結論

表欄位和表的字符集不一致,查詢的時候發生了隱式轉換。表欄位用了utf8mb4,表預設定義用utf8mb3,混合使用。導致batch_no是utf8mb4, number欄位是utf8mb3。

5解決方案

1、修改字符集
2、改寫SQL  select convert(batch_no using utf8) from ....

我個人覺得這個問題的根本原因還是SQL在上線的時候沒有做好稽核,缺乏SQL稽核工具與開發規範約束。

來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70027826/viewspace-3001859/,如需轉載,請註明出處,否則將追究法律責任。

相關文章