MySQL中where 1=1方法的使用及改進

背景

剛入行的同學,看到在SQL語句中出現where 1 = 1這樣的條件可能會有所困惑,而長時間這樣使用的朋友可能又習以為常。那麼,你是否還記得當初為什麼要這樣寫?是否有性能問題?有沒有更好的寫法?

今天這篇文章,帶大傢從頭到尾梳理一下where 1 = 1的使用及改進,或許你能從中得到更多意想不到的收獲。

where 1=1的作用

如果要問在SQL語句的where條件中多加1=1目的是什麼,很簡單:使得where條件語句永遠為真。本質上就是雖然加瞭where條件,但實際上永遠為真,也就相當於沒有加任何約束條件。

使用該語句的場景主要是:動態構建SQL語句

String sql  =  "select * from t_user  where 1=1 "; 
if(!b.equals("")){
  sql += "and  b='"+b+"'";
}   

在上述語句拼寫時,使用where 1=1,當b不等於空時,可以直接拼接“and”語句,而不會導致語法錯誤。如果沒有where 1=1,原來的SQL語句就變成(假設b傳入瞭"abc"):

"select * from t_user  where and  b= 'abc' "; 

很明顯,上述SQL語句會有語法錯誤。所以,之所以添加1=1,就是為瞭方便SQL拼接。

從另外一個角度來講,不僅僅1=1可以這樣使用,像:1<>22>1'a'='a'等表達式,隻要結果為true,都可以如此使用。

where 1<>1

上面講瞭where 1=1的來歷及使用,那麼你是否使用過where 1<>1的形式呢?

你還別說,where 1<>1也是有使用場景的,比如:隻獲取表結構而不取數據。

create table t_temp as select * from t_user  where 1<>1

上述語句,創建瞭一個與t_user表結構一樣但沒有任何數據的新表t_temp。

當然,除瞭表結構,其他的結構也可以如此使用。

where 1=1的性能問題

有人說,使用where 1=1可能會有性能問題,咱們直接來實驗一下。

mysql 8.0.18,t_user表,id_no字段有索引:

explain select * from t_user where id_no = 'Tom25';
explain select * from t_user where 1=1 and id_no = 'Tom25';

執行上述兩行SQL語句,explain結果都是如下:

也就是說,1=1這樣條件,並不影響索引和性能,從explain結果上可以看出兩者並無本質區別。

之所以不同的SQL語句,呈現瞭相同的結果,這是因為被Mysql優化瞭。Mysql在處理指令時,會對1=1這類無效的條件進行優化處理。這個與Java的編譯器有些像,很多無效的判斷或語句,在編譯成字節碼時,編譯器會進行優化處理。

where 1=1的改進

雖然說1=1會被優化器優化掉,但優化操作本身還是會消耗MySQL的性能的,如果能夠從根本上避免這種情況的出現,那不就更好瞭。

以Mybatis為例,在使用where 1=1時,通常會是如下寫法:

<select id="queryUser" parameterType="com.choupangxia.entity.User" resultType="java.lang.Integer">
  select count(id) from t_user u where 1=1
<if test="username !=null and username !='' ">
  AND u.username = #{username} 
</if> 
<if test="userNo !=null and userNo !='' ">
  AND u.user_no = #{userNo}
</if> 
</select>

這裡where 1=1的作用同上。但如果你更進一步去瞭解Mybatis的語法及標簽,可以使用<where>標簽來代替where 1=1

<select id="queryUser" parameterType="com.choupangxia.entity.User" resultType="java.lang.Integer">
  select count(id) from t_user u
<where>
<if test="username !=null and username !='' ">
 u.username = #{username} 
</if>
<if test="userNo !=null and userNo !='' ">
 AND u.user_no = #{userNo}
</if>
</where>
</select>

這樣,在查詢數據比較大的情況下,可減少MySQL為瞭優化1=1這樣的條件而損失的性能。

小結

本文我們從習以為常的where 1=1使用聊起,聊瞭它的使用場景、MySQL對其優化、以及延伸出來的where 1<>1的使用,同時基於常見的Mybatis框架,如何進一步改進。

其實,寫這篇文章想傳達的一個思想就是:再小,再習以為常的事物,如果你去思考、研究都會學到很多相關的知識點,也都可以對其進一步優化。

到此這篇關於MySQL中where 1=1方法的使用及改進的文章就介紹到這瞭,更多相關 MySQL where 1=1 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: