成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL的 where 1=1 會影響性能嗎?

數據庫 MySQL
在日常業務開發中,where 1=1和<where> 標簽到底會不會影響性能,本文將從官方文檔來進行說明。

在日常業務開發中,經常會使用where 1=1來簡化動態 SQL語句的拼接,有人說where 1=1會影響性能,也有人說不會,到底會不會影響性能?本文將從 MySQL的官方資料來進行分析。

一、動態拼接SQL

在 Mybatis中,動態拼接 SQL最常用的兩種方式:使用 where 1=1 和 使用<where>標簽。

1. 使用where 1=1

使用過 iBATIS的小伙伴應該都知道:在 iBATIS中沒有<where>標簽,動態 SQL的處理相對較為原始和復雜,因此使用where 1=1這種寫法的用戶很大一部分是還在使用 iBATIS 或者是從 iBATIS過度到 Mybatis。

如下示例,通過where 1=1來動態拼接有效的 if語句:

<select id="" parameterType = "">
 SELECT * FROM user 
 WHERE 1=1
    <if test="name != null and name != ''">
        AND name = #{name}
    </if>
    <if test="age != null ">
        AND age = #{age }
    </if>
</select>

2. 使用<where>標簽

Mybatis提供了<where>標簽,<where>標簽只有在至少一個 if條件有值的情況下才去生成 where子句,若 AND或 OR前沒有有效語句,where元素會將它們去除,也就是說,如果 Mybatis通過<where>標簽動態生成的語句為where AND name = '111',最終會被優化為where name = '111'。

<where>標簽使用示例如下:

<select id="" parameterType = "">
 SELECT * FROM user 
    <where>
        <if test="name != null and name != ''">
           AND name = #{name}
        </if>
        <if test="age != null">
           AND age = #{age}
        </if>
    </where>
</select>

<where>標簽是在 MyBatis中引入的,所以,很多一開始就使用 MyBatis的用戶對這個標簽使用的比較多。

二、性能影響

where 1=1到底會不會影響性能?我們可以先看一個具體的例子:

說明:示例基于 MySQL 8.0.30

可以使用如下指令查看 MySQL版本:

SELECT VERSION();

場景:基于一張擁有 100多萬條數據的user表,根據name進行查詢。

查看表結構和表的總數據,如下圖:

下面,通過執行兩條 SQL查詢語句(一條帶有 1=1):

select * from user where name = 'name-96d1b3ce-1a24-4d47-b686-6f9c6940f5f6';
select * from user where 1=1 and name = 'name-f692472e-40de-4053-9498-54b9800e9fb1';

對比兩條 SQL執行的結果,可以發現它們消耗的時間幾乎相同,因此,看起來where 1=1對整體的性能似乎并不影響。

為了排除一次查詢不具有代表性,我們分別對兩條 SQL語句查詢 100遍,然后計算平均值:

SET PROFILING = 1;
DO SLEEP(0.001); -- 確保每次查詢之間有足夠時間間隔

SET @count = 0;
WHILE @count < 100 DO
select * from user where name = 'name-96d1b3ce-1a24-4d47-b686-6f9c6940f5f6';
-- or
select * from user where 1=1 and name = 'name-f692472e-40de-4053-9498-54b9800e9fb1';
SET @count = @count + 1;
END WHILE;    

SHOW PROFILES;

兩條 SQL分別執行 100次后,最終也發現它們的平均值幾乎相同,因此,上述示例似乎證明了 where 1=1 對整體的性能并沒有不影響。

為什么沒有影響?是不是 MySQL對 1=1進行了優化?

為了證明猜想,我們借助show warnings命令來查看信息,在 MySQL中,show warnings命令用于顯示最近執行的 SQL語句產生的警告、錯誤或通知信息。它可以幫助我們了解語句執行過程中的問題。如下示例:

explain select * from user where 1=1 and name = 'name-f692472e-40de-4053-9498-54b9800e9fb1';
show warnings;

將上述示例的 warnings信息摘出來如下:

/* select#1 */ select `yuanjava`.`user`.`id` AS `id`,
      `yuanjava`.`user`.`name` AS `name`,
      `yuanjava`.`user`.`age` AS `age`,
      `yuanjava`.`user`.`sex` AS `sex`,
      `yuanjava`.`user`.`created_at` AS `created_at` 
from `yuanjava`.`user` 
where (`yuanjava`.`user`.`name` = 'name-f692472e-40de-4053-9498-54b9800e9fb1')

從 warnings信息可以看出:1=1已經被查詢優化器優化掉,因此,對整體的性能影響并不大。

那么,有沒有 MySQL的官方資料可以佐證 where 1=1確實被優化了?

答案:有!MySQL有一種 Constant-Folding Optimization(常量折疊優化)的功能。

三、Constant-Folding Optimization

MySQL的優化器具有一項稱為 Constant-Folding Optimization(常量折疊優化)的功能,可以從查詢中消除重言式表達式。Constant-Folding Optimization 是一種編譯器的優化技術,用于優化編譯時計算表達式的常量部分,從而減少運行時的計算量,換句話說:Constant-Folding Optimization 是發生在編譯期,而不是引擎執行期間。

對于上述表達的”重言式表達式”又是什么呢?

重言式

重言式(Tautology )又稱為永真式,它的漢語拼音為:[Chóng yán shì],是邏輯學的名詞。命題公式中有一類重言式,如果一個公式,對于它的任一解釋下其真值都為真,就稱為重言式(永真式)。

其實,重言式在計算機領域也具有重要應用,比如”重言式表達式”(Tautological expression),它指的是那些總是為真的表達式或邏輯條件。

在 SQL查詢中,重言式表達式是指無論在什么情況下,結果永遠為真,它們通常會被優化器識別并優化掉,以提高查詢效率。例如,如果 where中包含 1=1 或 A=A 這種重言式表達式,它們就會被優化器移除,因為對查詢結果沒有實際影響。如下兩個示例:

SELECT * from user where 1=1 and name = 'xxx';
-- 被優化成
SELECT * from user where name = 'xxx';

SELECT id, name, salary * (1 + 0.05 * 2) AS real_salary FROM employees;
-- 優化成(1 + 0.05 * 2 被優化成 1.1)
SELECT id, name, salary * 1.1 AS real_salary FROM employees;

另外,通過下面 MySQL架構示意圖可以看出:優化器是屬于 MySQL的 Server層,因此,Constant-Folding Optimization功能支持受 MySQL Server的版本影響。

查閱了 MySQL的官方資料,Constant-Folding Optimization 從 MySQL5.7版本開始引入,至于 MySQL5.7以前的版本是否具備這個功能,還有待考證。

四、如何選擇?

where 1=1 和 <where> 標簽 兩種方案,該如何選擇?

  • 如果 MySQL Server版本大于等于 5.7,兩個隨便選,或者根據團隊的要求來選;
  • 如果 MySQL Server版本小于 5.7,假如使用的是 MyBatis,建議使用<where> 標簽,如果使用的還是比較老的 iBATIS,只能使用where 1=1;

信息補充:2009年5月,iBATIS從 2.0版本開始更名為 MyBatis, 標簽最早出現在MyBatis 3.2.0版本中。

五、總結

where 1=1和<where> 標簽到底會不會影響性能,這個問題在網上已經出現了很多次,今天還是想從官方文檔來進行說明。本文通過 MySQL的官方資料,加上百萬數據的表進行真實測試,得出下面的結論:

  • 如果 MySQL Server版本大于等于 5.7,where 1=1 對于性能幾乎沒有影響,因此,兩個方式隨便選,或者根據團隊的要求來選;
  • 如果 MySQL Server版本小于 5.7,假如使用的是 MyBatis,建議使用<where> 標簽,如果使用的還是比較老的 iBATIS,只能使用where 1=1;

最后,遇到問題,建議首先查找官方的一手資料,這樣才能幫助自己在一條正確的技術道路上成長!

責任編輯:趙寧寧 來源: 猿java
相關推薦

2024-05-27 00:21:09

數據庫技巧SQL

2024-08-05 01:23:41

SQL語句MySQL

2010-09-08 15:51:53

SQL語句where

2011-03-10 13:18:54

SQLwhere

2022-03-01 07:37:30

MySQL場景框架

2024-11-04 08:20:00

try-catch編程

2021-11-15 06:56:45

MyBatis開發項目

2010-05-25 10:08:41

虛擬化高性能計算

2024-01-02 08:55:27

Linux緩存系統性能

2019-05-17 09:05:54

MySQL查詢性能數據庫

2014-04-01 09:52:46

MySQL

2023-09-20 14:54:17

MySQL

2021-06-28 17:21:49

MySQL性能Java

2023-12-28 07:35:44

數據庫場景Object

2020-11-05 09:33:37

SQL數據庫編程

2020-11-06 07:09:06

SQL注入編程

2022-11-05 08:37:00

MySQL數據索引

2021-09-16 06:44:07

數據庫SQL語句

2024-04-28 10:13:39

2019-12-03 08:29:39

代碼調優網絡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品国产综合久久久久 | 国产高清自拍视频在线观看 | 中文字幕亚洲一区 | 亚州中文字幕 | 久久亚洲视频网 | 中文av网站| 成年人免费在线视频 | 在线亚洲一区 | 成人高清在线视频 | 日韩影院在线 | 成人久久网 | 性色av网站| www国产成人免费观看视频,深夜成人网 | 91精品国产欧美一区二区成人 | 久久精品亚洲精品国产欧美 | 精品日韩 | 亚洲成人精品久久 | 亚洲精品在线免费观看视频 | 成人a在线 | 久久久久久国产免费视网址 | 中文字幕一区二区三区四区五区 | 欧美精品99 | 日韩欧美在线观看 | 日本久久精品 | 精品国产一区一区二区三亚瑟 | 91精品国产91久久久久久吃药 | 国产日产久久高清欧美一区 | 日本不卡一二三 | 成人av一区二区三区 | 欧美激情久久久 | 日韩视频中文字幕 | 欧美日韩毛片 | 欧美一区二区三区在线观看视频 | 欧美一级视频在线观看 | 亚洲精品2区 | 亚洲九九精品 | 91综合网 | 成人三级在线播放 | 三级黄色片在线观看 | 久草视频2| 91免费在线|