foreach 后面in 傳入的參數有1萬條,#和$是有效率區別的,$的效率遠高於#,上篇文章做了比較。
但沒達到我的理想結果。
1. 更改方式,把foreach 去掉,改成拼裝方式, 參數直接拼裝成 ‘1,2,3,4,5,6’ ,然后傳入mybatis 中,dev_id in ${devIds},這里只能用$, 不能用#,#加了引號,實際
到數據庫的SQL 是 dev_id in ('1,2,3,4,5,6') 而不是 dev_id in (1,2,3,4,5,6) ,所以查不到結果。但是更改成這樣,仍然比foreach的$ 提升一倍的時間,不理想。
2. 繼續更改方式,換成exists, 這貨和in 在主表數據和子表數據一樣多的情況,實際效率差不多,只有當主表數據比子表數據多,用in快,主表數據比子表數據少,用exists, 實際上我這里不是數據庫的瓶頸,把這條SQL傳入1萬條ID作為參數在客戶端的工具里查詢,花費也就100毫秒左右。所以,我打算用exists試一試。
<if test="devIds != null and devIds != ''"> and EXISTS (select 1 from (SELECT regexp_split_to_table(#{devIds},',') AS dev_id) AS vir where cast(vir.dev_id as BIGINT) = sd.id) </if>
把送來的devIds 字符串進行行轉列,然后進行exists, 我這里dev_id字段類型為BIGINT,數據庫為Postgresql。我把數據庫的數據由1萬改為100萬條數據,傳入的參數由1萬改成20萬,in 消耗的時間如下圖的cost1, 373秒:
exists 消耗的時間如下圖cost1 , 2秒不到:
這樣,就算是解決了in的效率問題。我們系統達不到100萬級別的數量級,可能最多就10萬。足矣