<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          不要再用where 1=1了!有更好的寫法!

          共 2036字,需瀏覽 5分鐘

           ·

          2022-03-15 16:56

          大家好,我是躍哥。說來慚愧,我平時用SQL查詢的時候,還真的經(jīng)常用 where 1=1 這個玩意兒,沒想到,啪啪打臉啊!

          背景

          剛入行的同學,看到在SQL語句中出現(xiàn)where 1 = 1這樣的條件可能會有所困惑,而長時間這樣使用的朋友可能又習以為常。

          那么,你是否還記得當初為什么要這樣寫?是否有性能問題?有沒有更好的寫法?

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

          where 1=1的作用

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

          使用該語句的場景主要是:動態(tài)構建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<>2、2>1、'a'='a'等表達式,只要結果為true,都可以如此使用。

          where 1<>1

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

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

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

          上述語句,創(chuàng)建了一個與t_user表結構一樣但沒有任何數(shù)據(jù)的新表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';

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

          索引

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

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

          where 1=1的改進

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

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

          "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>?

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

          "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>?

          這樣,在查詢數(shù)據(jù)比較大的情況下,可減少MySQL為了優(yōu)化1=1這樣的條件而損失的性能。

          小結

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

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

          曾經(jīng)有一個技術大佬說過:再簡單的一段代碼,如果將訪問量擴大100倍、1000倍,都可以會出現(xiàn)問題。不要停止思考和學習!





          1. ?2022:請對我的 Flag 好一點!

          2. 30歲生日,總結過去的一年,我哭了……

          瀏覽 55
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产激情视频手机在线 | 黄色片国产在线观看 | 特级欧美AAAAAA | 成年人激情网 | 日日碰狠狠添天天爽 |