exists sql用法_干貨!SQL性能優化,書寫高質量SQL語句

5fc9a4a1f71bda73b25850c648d2c6e7.png


寫SQL語句的時候我們往往關注的是SQL的執行結果,但是是否真的關注了SQL的執行效率,是否注意了SQL的寫法規范?

以下的干貨分享是在實際開發過程中總結的,希望對大家有所幫助!

1. limit分頁優化

當偏移量特別大時,limit效率會非常低。

SELECT id FROM A LIMIT 1000,10 很快

SELECT id FROM A LIMIT 90000,10 很慢

方案一

select id from A order by id limit 90000,10;

如果我們結合order by使用。很快,0.04秒就OK。 因為使用了id主鍵做索引!當然,是否能夠使用索引還需要根據業務邏輯來定,這里只是為了提醒大家,在分頁的時候還需謹慎使用!

方案二

select id from A order by id  between 90000 and 90010;

2.利用limit 1 、top 1 取得一行

有些業務邏輯進行查詢操作時(特別是在根據某一字段DESC,取最大一筆).可以使用limit 1 或者 top 1 來終止[數據庫索引]繼續掃描整個表或索引。

反例

SELECT id FROM A LIKE 'abc%' 

正例

SELECT id FROM A LIKE 'abc%' limit 1

3. 任何情況都不要用 select * from table ,用具體的字段列表替換"*",不要返回用不到的字段,避免全盤掃描!

4. 批量插入優化

反例

INSERT into person(name,age) values('A',24)INSERT into person(name,age) values('B',24)INSERT into person(name,age) values('C',24)

正例

INSERT into person(name,age) values('A',24),('B',24),('C',24),

sql語句的優化主要在于對索引的正確使用,而我們在開發中經常犯的錯誤便是對表進行全盤掃描,一來影響性能,而來耗費時間!

5.like語句的優化

反例

SELECT id FROM A WHERE name like '%abc%'

由于abc前面用了“%”,因此該查詢必然走全表查詢,除非必要(模糊查詢需要包含abc),否則不要在關鍵詞前加%

正例

SELECT id FROM A WHERE name like 'abc%'

6.where子句使用 in 或 not in 的優化

sql語句中 in 和 not in 的使用請慎用!使用in 或者 not in 會丟棄索引,從而進行全盤掃描!

方案一:between 替換 in

反例

SELECT id FROM A WHERE num in (1,2,3) 

正例

SELECT id FROM A WHERE num between 1 and 3

方案二:exist 替換 in

注:關于exist和in的用法,片尾有彩蛋~

反例

SELECT id FROM A WHERE num in (select num from B)

正例

SELECT num FROM A WHERE num exists (select 1 from B where B.num = A.num)

方案三:left join 替換 in

反例

SELECT id FROM A WHERE num in (select num from B) 

正例

SELECT id FROM A LEFT JOIN B ON A.num = B.num

7.where子句使用or的優化

通常使用 union all 或 union 的方式替換“or”會得到更好的效果。where子句中使用了or關鍵字,索引將被放棄使用。

反例

SELECT id FROM A WHERE num = 10 or num = 20

正例

SELECT id FROM A WHERE num = 10 union all SELECT id FROM A WHERE num=20

8.where子句中使用 IS NULL 或 IS NOT NULL 的優化

反例

SELECT id FROM A WHERE num IS NULL

在where子句中使用 IS NULL 或 IS NOT NULL 判斷,索引將被放棄使用,會進行全表查詢。

正例

優化成num上設置默認值0,確保表中num沒有null值, IS NULL 的用法在實際業務場景下SQL使用率極高,我們應注意避免全表掃描

SELECT id FROM A WHERE num=0

9.where子句中對字段進行表達式操作的優化

不要在where子句中的“=”左邊進行函數、算數運算或其他表達式運算,否則系統將可能無法正確使用索引。

  • 1
SELECT id FROM A WHERE datediff(day,createdate,'2019-11-30')=0 

優化為

SELECT id FROM A WHERE createdate>='2019-11-30' and createdate
  • 2
SELECT id FROM A WHERE year(addate) <2020

優化為

SELECT id FROM A where addate

10.排序的索引問題?

mysql查詢只是用一個索引,因此如果where子句中已經使用了索引的話,那么order by中的列是不會使用索引。因此數據庫默認排序可以符合要求情況下不要使用排序操作;

盡量不要包含多個列的排序,如果需要最好給這些列創建復合索引

11. 盡量用 union all 替換 union

union和union all的差異主要是前者需要將兩個(或者多個)結果集合并后再進行唯一性過濾操作,這就會涉及到排序,增加大量的cpu運算,加大資源消耗及延遲。所以當我們可以確認不可能出現重復結果集或者不在乎重復結果集的時候,盡量使用union all而不是union

12.Inner join 和 left join、right join、子查詢

  • 第一:inner join內連接也叫等值連接是,left/rightjoin是外連接。
SELECT A.id,A.name,B.id,B.name FROM A LEFT JOIN B ON A.id =B.id;SELECT A.id,A.name,B.id,B.name FROM A RIGHT JOIN ON B A.id= B.id;SELECT A.id,A.name,B.id,B.name FROM A INNER JOIN ON A.id =B.id;

經過來之多方面的證實 inner join性能比較快,因為inner join是等值連接,或許返回的行數比較少。但是我們要記得有些語句隱形的用到了等值連接,如:

SELECT A.id,A.name,B.id,B.name FROM A,B WHERE A.id = B.id;

推薦:能用inner join連接盡量使用inner join連接

  • 第二:子查詢的性能又比外連接性能慢,盡量用外連接來替換子查詢。

反例

mysql是先對外表A執行全表查詢,然后根據uuid逐次執行子查詢,如果外層表是一個很大的表,我們可以想象查詢性能會表現比這個更加糟糕。

Select* from A where exists (select * from B where id>=3000 and A.uuid=B.uuid);

執行時間:2s左右

正例

Select* from A inner join B ON A.uuid=B.uuid where b.uuid>=3000;  這個語句執行測試不到一秒;

執行時間:1s不到

  • 第三:使用JOIN時候,應該用小的結果驅動大的結果

left join 左邊表結果盡量小,如果有條件應該放到左邊先處理,right join同理反向。如:

反例

Select * from A left join B A.id=B.ref_id where  A.id>10

正例

select * from (select * from A wehre id >10) T1 left join B on T1.id=B.ref_id;

13.exist 代替 in

反例

SELECT * from A WHERE id in ( SELECT id from B )

正例

SELECT * from A WHERE id EXISTS ( SELECT 1 from A.id= B.id )

分析:

in 是在內存中遍歷比較

exist 需要查詢數據庫,所以當B的數據量比較大時,exists效率優于in**

in()只執行一次,把B表中的所有id字段緩存起來,之后檢查A表的id是否與B表中的id相等,如果id相等則將A表的記錄加入到結果集中,直到遍歷完A表的所有記錄。

In 操作的流程原理如同一下代碼

    List resultSet={};    Array A=(select * from A);    Array B=(select id from B);    for(int i=0;i

可以看出,當B表數據較大時不適合使用in(),因為會把B表數據全部遍歷一次

如:A表有10000條記錄,B表有1000000條記錄,那么最多有可能遍歷10000*1000000次,效率很差。

再如:A表有10000條記錄,B表有100條記錄,那么最多有可能遍歷10000*100次,遍歷次數大大減少,效率大大提升。

??結論:in()適合B表比A表數據小的情況

exist()會執行A.length()次,執行過程代碼如下

List resultSet={};Array A=(select * from A);for(int i=0;i

當B表比A表數據大時適合使用exists(),因為它沒有那么多遍歷操作,只需要再執行一次查詢就行。

如:A表有10000條記錄,B表有1000000條記錄,那么exists()會執行10000次去判斷A表中的id是否與B表中的id相等。

如:A表有10000條記錄,B表有100000000條記錄,那么exists()還是執行10000次,因為它只執行A.length次,可見B表數據越多,越適合exists()發揮效果。

再如:A表有10000條記錄,B表有100條記錄,那么exists()還是執行10000次,還不如使用in()遍歷10000*100次,因為in()是在內存里遍歷比較,而exists()需要查詢數據庫,

我們都知道查詢數據庫所消耗的性能更高,而內存比較很快。 ?

結論:exists()適合B表比A表數據大的情況

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/538763.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/538763.shtml
英文地址,請注明出處:http://en.pswp.cn/news/538763.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python docker自動化_「docker實戰篇」python的docker爬蟲技術-移動自動化控制工具appium工具(17)...

原創文章&#xff0c;歡迎轉載。轉載請注明&#xff1a;轉載自IT人故事會&#xff0c;謝謝&#xff01;原文鏈接地址&#xff1a;「docker實戰篇」python的docker爬蟲技術-移動自動化控制工具appium工具(17)Appium是一個開源測試自動化框架&#xff0c;可用于原生&#xff0c;混…

一些adb的常用命令

顯示正在運行的服務 adb shell dumpsys activity services [packageName] 打開一個Activity adb shell am start -n &#xff5b;包(package)名&#xff5d;/Activity絕對路徑(ex:com.xxx.xxx.xxxActivity) 以調試模式啟動一個Activity adb shell am start -D -n &#xff5b;包…

android 調用restful,android調用springmvc寫的restful

下載srpingmvc的相關jarhttp://www.cnblogs.com/liuhongfeng/p/4919963.html配置spingmvc和相關接口http://blog.csdn.net/jianyuerensheng/article/details/51258942如果報錯&#xff0c;檢查JDK版本是否和本地的一致在UserController.jave中添加接口package com.zjn.controll…

eureka server配置_springcloud項目搭建第三節:eureka集群

在上一節搭建的項目基礎上&#xff0c;在創建一個eureka-server-two的子項目和eureka-server項目一樣&#xff0c;然后修改各自項目的application.yml文件eureka-server項目的application.yml文件修改2點1.修改eureka的注冊地址改成另一個eureka-server-two項目的注冊中心地址2…

15.浮點類型

數值范圍 float類型又被稱為單精度類型&#xff0c;尾數可以精確到7位有效數字&#xff0c;在很多情況下&#xff0c;float類型的精度很難滿足需求。 double類型又被稱為雙精度類型&#xff0c;尾數可以精確到14位有效數字。 浮點類型默認是double。 public static void main(…

c4d流體插件_(圖文+視頻)C4D野教程:TFD、XP和RF三大流體插件協作案例

在逛INS的時候&#xff0c;看見國外一位叫做BastardFilms的大神制作了很多流體的效果&#xff1a;尤其是他制作的很多液態煙霧的流體&#xff0c;我特別喜歡&#xff0c;由于我不知道怎么下載INS的視頻&#xff0c;所以這里只有發個截圖大家看看&#xff1a;作者這里有說明是用…

form表單用js提前執行函數若不成功則不提交_面試必會的重復提交 8 種解決方案!...

重復提交看似是一個小兒科的問題&#xff0c;但卻存在好幾種變種用法。在面試中回答的好&#xff0c;說不定會有意想不到的收獲&#xff01;現把這 8 種解決方案分享給大家&#xff01;1.什么是冪等在我們編程中常見冪等select查詢天然冪等delete刪除也是冪等,刪除同一個多次效…

16.char類型

char&#xff0c;占2個字節。 單引號用來表示字符常量。例如a. char類型用來表示在Unicode編碼表中的字符。 unicode編碼被設計用來處理各種語言的所有文字&#xff0c;它占了2個字節&#xff0c;可允許有65536個字符。 Java語言中還允許使用轉義字符‘\&#xff0c;來將其后的…

轉向Kotlin——數據類和封閉類

數據類和封閉類是Kotlin中的兩種特殊的類&#xff0c;今天一起了解一下。更多精彩內容也可以關注我的微信公眾號——Android機動車 數據類 數據類是Kotlin的一個語法糖。Kotlin編譯器會自動為數據類生成一些成員函數&#xff0c;以提高開發效率。 數據類的使用 無論是Java服務器…

idea前端可視化_jsp可視化開發工具_netbeans jsp可視化_idea 可視化開發 jsp

數字生態鉅惠來襲&#xff01;秒殺 2核4G 5M帶寬 1200元/3年&#xff0c;1核1G首購 99元/年把默認改成 myeclipse jsp editor()原默認的jsp編輯器是 myeclipse visual jspdesigner&#xff0c;顧名思義&#xff0c;此編譯器是jsp可視化編輯器&#xff0c;對于初學者有很多的幫助…

開博爾智能android播放器,高端安卓播放器的選擇——開博爾Q10Plus 二代 4K高清播放器...

隨著OPPO和三星相繼宣布退出4K藍光播放器市場&#xff0c;先鋒的新機遲遲無法大量鋪貨&#xff0c;現在市面上可選擇的4K播放器就比較少了&#xff0c;價格也很高了&#xff0c;于是很多人開始將注意力轉向了安卓機&#xff0c;其中開博爾是比較有代表性的廠家了&#xff0c;這…

17.類型轉換

自動類型轉換 容量小的數據類型可以自動轉換為容量大的數據類型 byte b 123;//byte b2 300;//報錯&#xff0c;超過了byte最大值127//char c -3;//報錯&#xff0c;char范圍是0~65536&#xff0c;不在范圍char c2 a;//a在ascii碼里是98int i c2;long d01 123213;float f…

docker rabbitmq_一文看懂Rabbitmq,從安裝到實戰演練

Rabbitmq的初步使用隨著微服務概念發展&#xff0c;大應用逐步拆分為小應用&#xff0c;提高開發效率&#xff0c;專門的人做專門的事情&#xff0c;逐漸的流行起來。在微服務上實現通信的方式大部分是采用rpc方式&#xff0c;也有升級版本的grpc。還有另外一種實現就是使用mq來…

Angular v6 正式發布

Angular 6 正式發布 Angular 6 已經正式發布了&#xff01;這個主要版本并不關注于底層的框架&#xff0c;更多地關注于工具鏈&#xff0c;以及使 Angular 在未來更容易快速推進。 作為發布的一部分&#xff0c;我們同步了主要的框架包 (angular/core, angular/common, angula…

bootstrap五星評分_如何用純代碼實現評分星級顯示?

showRatingStars/*** showRatingStars 顯示評分星級* param {Object} myCanvas 畫布對象* param {Number} rating 評分* param {Number} counts star個數* param {Number} size star大小* param {Object} style star樣式* Example: style {* borderColor:"#21DEEF",…

18.變量

Java是一種強類型語言&#xff0c;每個變量都必須聲明其類型。 Java變量是程序中最基本的存儲單元&#xff0c;其要素包括變量名&#xff0c;變量類型和作用域。 變量在使用前必須對其聲明&#xff0c;只有在變量聲明以后&#xff0c;才能為其分配相應長度的存儲單元。 注意事項…

alertdialog android api 11,android – 設備api級別11的DialogFragments

我設法在兼容包的DialogFragment.java中正確修復了這個問題&#xff1a;改變第74行&#xff1a;boolean mShowsDialog false;注釋掉第232行&#xff1a;// mShowsDialog mContainerId 0;然后將兩個show方法更改為&#xff1a;public void show(FragmentManager manager, Str…

py 字典添加多個value_# Python 3 # Python 3字典Dictionary(1)

Python3 字典字典是另一種可變容器模型&#xff0c;且可存儲任意類型對象。字典的每個鍵值(key>value)對用冒號(:)分割&#xff0c;每個對之間用逗號(,)分割&#xff0c;整個字典包括在花括號({})中 ,格式如下所示&#xff1a;d {key1 : value1, key2 : value2 }鍵必須是唯…

饒軍:Apache Kafka的過去,現在,和未來

歡迎大家前往騰訊云社區&#xff0c;獲取更多騰訊海量技術實踐干貨哦~ 本文首發在云社區&#xff0c;未經許可&#xff0c;不得轉載。大家好&#xff0c;我大概簡單的介紹一下&#xff0c;我叫饒軍&#xff0c;我是硅谷的初創公司Con?uent的聯合創始人之一&#xff0c;我們公司…

機器人 樹莓派 自閉癥_用機器人孩子提高社交能力 讓自閉兒童走出自閉

一項由耶魯大學的研究團隊研究發現&#xff0c;通過讓患有自閉癥譜系障礙(autism spectrum disorders,ASD)的孩童與機器人相處一個月&#xff0c;極大地提高了自閉癥兒童的社交能力。耶魯大學研究中的機器人可以通過眼神接觸和模仿其它社交行為&#xff0c;通過講故事和互動游戲…