昨天偶然看見一篇文章,提到說如果在mysql查詢語句中,使用where 1=1
會有效能問題! 這著實把我吸引了,因為我專案中就有不少同事,包括我自己也有這樣寫的。爲了不給其他人挖坑,趕緊學習一下,這樣寫sql到底有沒有效能問題?
where 1=1
的使用場景
我們來看下,where 1=1
實際是怎麼使用的, 先來看一段SQL
<select id="selectCmsCourseList" parameterType="java.util.Map" resultMap="CourseMap"> SELECT a.id, a.category_id, a.model_id, b.* FROM cms_content a LEFT JOIN cms_course b ON a.id = b.id WHERE 1=1 <if test="courseName != null and courseName != ''"> AND b.course_name like concat(concat("%",#{courseName}),"%") </if> <if test="disabled != null"> AND a.disabled = #{disabled} </if> <if test="categoryId != null"> AND a.category_id = #{categoryId} </if> </select>
如果用過mybatis的童鞋,看到這段程式碼應該很熟悉了吧,這裏使用where 1=1
的作用,就是爲了方便後面的條件,能透過if
判斷,使用AND
連線起來,這樣即使後面if
全部是false
,沒有引數,這個sql
也不會報錯。
where 1=1
的替換方案
其實上面的這個寫法,如果用mybatis,完全可以用where
標籤來替換,如:
<select id="selectCmsCourseList" parameterType="java.util.Map" resultMap="CourseMap"> SELECT a.id, a.category_id, a.model_id, b.* FROM cms_content a LEFT JOIN cms_course b ON a.id = b.id <where> <if test="courseName != null and courseName != ''"> AND b.course_name like concat(concat("%",#{courseName}),"%") </if> <if test="disabled != null"> AND a.disabled = #{disabled} </if> <if test="categoryId != null"> AND a.category_id = #{categoryId} </if> </where> </select>
如果你使用了這個寫法,就不存在1=1
的問題了,所以也不用糾結,但本著打破砂鍋問到底的精神,我們還是得探究一下使用1=1
到底有沒有效能問題
使用where 1=1
有效能問題嗎?
先來問問AI
可以看到,AI給到的答覆是,基本沒有效能問題,更多的是程式碼風格和可讀性!
親自檢測
爲了跟進一步測試,我們來寫個SQL看看實際效能是否有差別
explain select * from user;
explain select * from user where 1=1;
explain select * from user where id = 8;
explain select * from user where 1=1 and id = 8;
可以看到示例1和示例2, 示例3和示例4,這兩組寫法,都是有個1=1
的區別,但效能都是一樣的,因此我們基本可以判定,這個寫法,對效能是沒有影響的。
總結
如果你在專案中也有使用where 1=1
寫的SQL,如果從可讀性或者程式碼風格考慮,建議最佳化掉,但如果擔心效能問題,則大可不必過多考慮~