MySQL中where?1=1方法的使用及改進(jìn)
背景
剛?cè)胄械耐瑢W(xué),看到在SQL語(yǔ)句中出現(xiàn)where 1 = 1
這樣的條件可能會(huì)有所困惑,而長(zhǎng)時(shí)間這樣使用的朋友可能又習(xí)以為常。那么,你是否還記得當(dāng)初為什么要這樣寫?是否有性能問題?有沒有更好的寫法?
今天這篇文章,帶大家從頭到尾梳理一下where 1 = 1
的使用及改進(jìn),或許你能從中得到更多意想不到的收獲。
where 1=1的作用
如果要問在SQL語(yǔ)句的where條件中多加1=1
目的是什么,很簡(jiǎn)單:使得where條件語(yǔ)句永遠(yuǎn)為真。本質(zhì)上就是雖然加了where條件,但實(shí)際上永遠(yuǎn)為真,也就相當(dāng)于沒有加任何約束條件。
使用該語(yǔ)句的場(chǎng)景主要是:動(dòng)態(tài)構(gòu)建SQL語(yǔ)句。
String sql = "select * from t_user where 1=1 "; if(!b.equals("")){ sql += "and b='"+b+"'"; } ?
在上述語(yǔ)句拼寫時(shí),使用where 1=1
,當(dāng)b不等于空時(shí),可以直接拼接“and”語(yǔ)句,而不會(huì)導(dǎo)致語(yǔ)法錯(cuò)誤。如果沒有where 1=1
,原來(lái)的SQL語(yǔ)句就變成(假設(shè)b傳入了"abc"):
"select * from t_user where and b= 'abc' ";
很明顯,上述SQL語(yǔ)句會(huì)有語(yǔ)法錯(cuò)誤。所以,之所以添加1=1
,就是為了方便SQL拼接。
從另外一個(gè)角度來(lái)講,不僅僅1=1
可以這樣使用,像:1<>2
、2>1
、'a'='a'
等表達(dá)式,只要結(jié)果為true,都可以如此使用。
where 1<>1
上面講了where 1=1
的來(lái)歷及使用,那么你是否使用過where 1<>1
的形式呢?
你還別說,where 1<>1
也是有使用場(chǎng)景的,比如:只獲取表結(jié)構(gòu)而不取數(shù)據(jù)。
create table t_temp as select * from t_user where 1<>1
上述語(yǔ)句,創(chuàng)建了一個(gè)與t_user表結(jié)構(gòu)一樣但沒有任何數(shù)據(jù)的新表t_temp。
當(dāng)然,除了表結(jié)構(gòu),其他的結(jié)構(gòu)也可以如此使用。
where 1=1的性能問題
有人說,使用where 1=1
可能會(huì)有性能問題,咱們直接來(lái)實(shí)驗(yàn)一下。
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';
執(zhí)行上述兩行SQL語(yǔ)句,explain結(jié)果都是如下:
也就是說,1=1
這樣條件,并不影響索引和性能,從explain結(jié)果上可以看出兩者并無(wú)本質(zhì)區(qū)別。
之所以不同的SQL語(yǔ)句,呈現(xiàn)了相同的結(jié)果,這是因?yàn)楸籑ysql優(yōu)化了。Mysql在處理指令時(shí),會(huì)對(duì)1=1
這類無(wú)效的條件進(jìn)行優(yōu)化處理。這個(gè)與Java的編譯器有些像,很多無(wú)效的判斷或語(yǔ)句,在編譯成字節(jié)碼時(shí),編譯器會(huì)進(jìn)行優(yōu)化處理。
where 1=1的改進(jìn)
雖然說1=1會(huì)被優(yōu)化器優(yōu)化掉,但優(yōu)化操作本身還是會(huì)消耗MySQL的性能的,如果能夠從根本上避免這種情況的出現(xiàn),那不就更好了。
以Mybatis為例,在使用where 1=1
時(shí),通常會(huì)是如下寫法:
<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
的作用同上。但如果你更進(jìn)一步去了解Mybatis的語(yǔ)法及標(biāo)簽,可以使用<where>
標(biāo)簽來(lái)代替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>
這樣,在查詢數(shù)據(jù)比較大的情況下,可減少M(fèi)ySQL為了優(yōu)化1=1
這樣的條件而損失的性能。
小結(jié)
本文我們從習(xí)以為常的where 1=1
使用聊起,聊了它的使用場(chǎng)景、MySQL對(duì)其優(yōu)化、以及延伸出來(lái)的where 1<>1
的使用,同時(shí)基于常見的Mybatis框架,如何進(jìn)一步改進(jìn)。
其實(shí),寫這篇文章想傳達(dá)的一個(gè)思想就是:再小,再習(xí)以為常的事物,如果你去思考、研究都會(huì)學(xué)到很多相關(guān)的知識(shí)點(diǎn),也都可以對(duì)其進(jìn)一步優(yōu)化。
到此這篇關(guān)于MySQL中where 1=1方法的使用及改進(jìn)的文章就介紹到這了,更多相關(guān) MySQL where 1=1 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一文帶你了解如何用MySQL通配符實(shí)現(xiàn)過濾功能
本文章將介紹什么是通配符、如何使用通配符以及怎樣使用LIKE操作符進(jìn)行通配搜索,以便對(duì)數(shù)據(jù)進(jìn)行復(fù)雜過濾,感興趣的小伙伴跟著小編一起來(lái)學(xué)習(xí)吧2023-07-07巧用mysql提示符prompt清晰管理數(shù)據(jù)庫(kù)的方法
隨著管理mysql服務(wù)器越來(lái)越多,同樣的mysql>的提示符有可能會(huì)讓你輸入錯(cuò)誤的命令到錯(cuò)誤的數(shù)據(jù)庫(kù),這時(shí)候需要巧用mysql的提示符,這是我的提示符root@localhost(mysql) 08:55:21> 用prompt命令實(shí)現(xiàn)(適用于windows和linux環(huán)境)2009-08-08MySql數(shù)據(jù)分區(qū)操作之新增分區(qū)操作
這篇文章主要介紹了MySql數(shù)據(jù)分區(qū)操作之新增分區(qū)操作,本文講解了測(cè)試創(chuàng)建分區(qū)表文件、插入測(cè)試數(shù)據(jù)、查詢P2中的數(shù)據(jù)等內(nèi)容,需要的朋友可以參考下2015-03-03mysql5.6.19下子查詢?yōu)槭裁礋o(wú)法使用索引
這篇文章主要介紹了mysql5.6.19下子查詢?yōu)槭裁礋o(wú)法使用索引,需要的朋友可以參考下2014-08-08詳解MySQL執(zhí)行原理、邏輯分層、更改數(shù)據(jù)庫(kù)處理引擎
在本文里我們給大家總結(jié)了關(guān)于MySQL執(zhí)行原理、邏輯分層、更改數(shù)據(jù)庫(kù)處理引擎的相關(guān)知識(shí)點(diǎn),需要的讀者們一起學(xué)習(xí)下。2019-02-02MySQL 5.6 中的 TIMESTAMP 和 explicit_defaults_for_timestamp 參數(shù)
這篇文章主要介紹了MySQL 5.6 中的 TIMESTAMP 和 explicit_defaults_for_timestamp 參數(shù),需要的朋友可以參考下2015-08-08MySQL?中的count(*)?與?count(1)?誰(shuí)更快一些?
這篇文章主要討論MySQL?中?count(*)?與?count(1)?誰(shuí)更快一些?以下討論基于?InnoDB?存儲(chǔ)引擎,并且再文末單獨(dú)說一下MyISAM?,感興趣的小伙伴可以參考一下2022-02-02