一. MyBatis SQL語句遇到的性能問題
1. 場景還原
假設我們有一張User表,其中包含userId、userName、gender字段,其中userId的數據類型為char(20),此時我們想通過userId獲得這個人的姓名,
這段SQL很簡單: SELECT userName FROM dbo.User (nolock) WHERE userId = '100'
2. 問題描述
上面這段簡單的SQL語句卻隱藏着很一個嚴重的性能問題:當MyBatis生成該語句,並在SQL Server執行時,參數userId的JDBC Type為nvarchar(4000),但表中userId的數據類型為char(20),因此必然存在着類型轉換。
在壓力測試場景、或調用頻繁的情況下,導致SQL Server CPU嚴重超標,以及服務吞吐量嚴重下降。
二. char、varchar、nvarchar區別
- char:對於英文字母占1個字節,對於漢字占2個字節,char屬於定長類型數據結構,剩余空間全部使用空格填補,因此索引效率極高。
- varchar: 多余空間不會使用空格填補,實際長度為字符串長度+1,這個1代表字符串的長度。
- nvarchar:所有的字符都占用2個字節,無論英文字母,還是漢字。解決了多字符集之間的轉換問題,N代表Unicode。