最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

explain慢查詢SQL調(diào)優(yōu)exists的實戰(zhàn)

 更新時間:2023年12月02日 14:49:13   作者:蘇三說技術(shù)  
這篇文章主要介紹了explain慢查詢SQL調(diào)優(yōu)exists的實戰(zhàn),經(jīng)過兩次優(yōu)化SQL語句之后,慢SQL的性能顯著提升了,耗時從8s優(yōu)化到了0.7s,現(xiàn)在拿出來給大家分享一下,希望對你會有所幫助

最近我在公司優(yōu)化了一些慢查詢SQL,積累了一些SQL調(diào)優(yōu)的實戰(zhàn)經(jīng)驗。這篇文章從實戰(zhàn)的角度出發(fā),給大家分享一下如何做SQL調(diào)優(yōu)。

經(jīng)過兩次優(yōu)化之后,慢SQL的性能顯著提升了,耗時從8s優(yōu)化到了0.7s

現(xiàn)在拿出來給大家分享一下,希望對你會有所幫助。

1 案發(fā)現(xiàn)場

前幾天,我收到了一封報警郵件,提示有一條慢查詢SQL。

我打開郵件查看了詳情,那條SQL大概是這樣的:

SELECT count(*)
FROM spu s1
WHERE EXISTS (
 SELECT *
 FROM sku s2
  INNER JOIN mall_sku s3 ON s3.sku_id = s2.id
 WHERE s2.spu_id = s1.id
  AND s2.status = 1
  AND NOT EXISTS (
   SELECT *
   FROM supplier_sku s4
   WHERE s4.mall_sku_id = s3.id
    AND s4.supplier_id = 123456789
    AND s4.status = 1
  )
)

這條SQL的含義是統(tǒng)計id=123456789的供應(yīng)商,未發(fā)布的spu數(shù)量是多少。

這條SQL的耗時竟然達標了8s,必須要做優(yōu)化了。

我首先使用explain關(guān)鍵字查詢該SQL的執(zhí)行計劃,發(fā)現(xiàn)spu表走了type類型的索引,而sku、mall_sku、supplier_sku表都走了ref類型的索引。

也就是說,這4張表都走了索引。

不是簡單的增加索引,就能解決的事情。

那么,接下來該如何優(yōu)化呢?

2 第一次優(yōu)化

這條SQL語句,其中兩個exists關(guān)鍵字引起了我的注意。

一個exists是為了查詢存在某些滿足條件的商品,另一個not exists是為了查詢出不存在某些商品。

這個SQL是另外一位已離職的同事寫的。

不清楚spu表和sku表為什么不用join,而用了exists。

我猜測可能是為了只返回spu表的數(shù)據(jù),做的一種處理。如果join了sku表,則可能會查出重復(fù)的數(shù)據(jù),需要做去重處理。

從目前看,這種寫性能有瓶頸。

因此,我做出了第一次優(yōu)化。

使用join + group by組合,將sql優(yōu)化如下:

SELECT count(*) FROM
(
  select s2.spu_id from spu s1
  inner join from sku s2
  inner join mall_sku s3 on s3.sku_id=s2.id
  where s2.spu_id=s1.id and s2.status=1
  and not exists 
  (
     select * from supplier_sku s4
     where s4.mall_sku_id=s3.id
     and s4.supplier_id=...
  )
  group by s2.spu_id
) a

文章中有些相同的條件省略了,由于spu_id在sku表中是增加了索引的,因此group by的性能其實是挺快的。

這樣優(yōu)化之后,sql的執(zhí)行時間變成了2.5s

性能提升了3倍多,但是還是不夠快,還需要做進一步優(yōu)化。

3 第二次優(yōu)化

還有一個not exists可以優(yōu)化一下。

如果是小表驅(qū)動大表的時候,使用not exists確實可以提升性能。

但如果是大表驅(qū)動小表的時候,使用not exists可能有點弄巧成拙。

這里exists右邊的sql的含義是查詢某供應(yīng)商的商品數(shù)據(jù),而目前我們平臺一個供應(yīng)商的商品并不多。

于是,我將not exists改成了not in。

sql優(yōu)化如下:

SELECT count(*) FROM
(
  select s2.spu_id from spu s1
  inner join from sku s2
  inner join mall_sku s3 on s3.sku_id=s2.id
  where s2.spu_id=s1.id and s2.status=1
  and s3.id not IN 
  (
     select s4.mall_sku_id 
     from supplier_sku s4
     where s4.mall_sku_id=s3.id
     and s4.supplier_id=...
  )
  group by s2.spu_id
) a

這樣優(yōu)化之后,該sql的執(zhí)行時間下降到了0.7s。

之后,我再用explain關(guān)鍵字查詢該SQL的執(zhí)行計劃。

發(fā)現(xiàn)spu表走了全表掃描,sku表走了eq_ref類型的索引,而mall_sku和supplier_sku表走了ref類型的索引。

可以看出,有時候sql語句走了4個索引,性能未必比走了3個索引好。

多張表join的時候,其中一張表走了全表掃描,說不定整個SQL語句的性能會更好,我們一定要多測試。

exists和not exists常用示例說明

1.查詢a表在b表中存在數(shù)據(jù)

相當于sql中in操作。

select * from a where exists (select 1 from b where a_id=a.id )

以上sql等價于下面的sql

select * from a where id in (select a_id from b)

2.查詢a表在b表中不存在數(shù)據(jù)

相當于sql中not in操作。

select * from a where not exists (select 1 from b where a_id=a.id )

以上sql等價于下面的sql

select * from a where id not in (select a_id from b)

3.查詢時間最新記錄

以下sql查詢同一id內(nèi)的c_date最近的記錄。

SELECT * FROM c t1
   WHERE NOT EXISTS(select * from c where id = t1.id and c_date>t1.c_date)

分析:子查詢中,先看id = 1 的情形,只有當t1.c_date 取最大值時,沒有返回結(jié)果,因為是NOT EXISTS關(guān)鍵字,所以Where條件成立,返回符合條件的查詢結(jié)果

4.exists替代distinct剔除重復(fù)數(shù)據(jù)

例如下面sql

SELECT distinct a.id,a.name from a, b WHERE a.id=b.a_id;

使用exists提出重復(fù),等價于上面的sql

select id,name from a where exists (select 1 from b where a_id=a.id );

分析:RDBMS 核心模塊將在子查詢的條件一旦滿足后,立即返回結(jié)果,所以自帶去重

總結(jié)

說實話,SQL調(diào)優(yōu)是一個比較復(fù)雜的問題,需要考慮的因素有很多,有可能需要多次優(yōu)化才能滿足要求。

到此這篇關(guān)于explain慢查詢SQL調(diào)優(yōu)exists的實戰(zhàn)的文章就介紹到這了,更多相關(guān)慢查詢SQL調(diào)優(yōu)exists內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用 Navicat 創(chuàng)建數(shù)據(jù)庫并用JDBC連接的操作方法

    使用 Navicat 創(chuàng)建數(shù)據(jù)庫并用JDBC連接的操作方法

    這篇文章主要介紹了使用 Navicat 創(chuàng)建數(shù)據(jù)庫并用JDBC連接的操作方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Navicat12.1系列破解激活教程親測有效

    Navicat12.1系列破解激活教程親測有效

    這篇文章主要介紹了 Navicat12.1系列破解激活教程親測有效,本文給大家介紹的非常詳細,對大家的學習或工作工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • node-mysql中防止SQL注入的方法總結(jié)

    node-mysql中防止SQL注入的方法總結(jié)

    大家都知道SQL注入對于網(wǎng)站或者服務(wù)器來講都是一個非常危險的問題,如果這一方面沒處理好的話網(wǎng)站可能隨時給注入了,所以這篇文章就給大家總結(jié)了node-mysql中防止SQL注入的幾種常用做法,有需要的朋友們可以參考借鑒。
    2016-10-10
  • 關(guān)于Navicat連接MySql數(shù)據(jù)庫慢的問題

    關(guān)于Navicat連接MySql數(shù)據(jù)庫慢的問題

    這篇文章主要介紹了關(guān)于Navicat連接MySql數(shù)據(jù)庫慢的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • 淺談關(guān)系型數(shù)據(jù)庫中的約束及應(yīng)用場景

    淺談關(guān)系型數(shù)據(jù)庫中的約束及應(yīng)用場景

    這篇文章主要介紹了淺談關(guān)系型數(shù)據(jù)庫中的約束及應(yīng)用場景,關(guān)系型數(shù)據(jù)庫是一種廣泛應(yīng)用的數(shù)據(jù)庫類型,它的核心是基于關(guān)系模型的結(jié)構(gòu)化數(shù)據(jù)存儲和管理,在關(guān)系型數(shù)據(jù)庫中,約束是一種重要的概念,它可以幫助我們保證數(shù)據(jù)的完整性和一致性,需要的朋友可以參考下
    2023-07-07
  • MySQL與Oracle 差異比較之七 其它

    MySQL與Oracle 差異比較之七 其它

    這篇文章主要介紹了MySQL與Oracle 差異比較之七 其它,需要的朋友可以參考下
    2017-04-04
  • SQLite Limit 子句的使用小結(jié)

    SQLite Limit 子句的使用小結(jié)

    LIMIT子句用于限制查詢結(jié)果的數(shù)量,在SQLite中,LIMIT子句可以單獨使用,也可以與OFFSET子句結(jié)合使用,有助于提高數(shù)據(jù)庫查詢的效率和質(zhì)量,感興趣的可以了解一下
    2025-12-12
  • Navicat?Premium?12數(shù)據(jù)庫管理解決方案

    Navicat?Premium?12數(shù)據(jù)庫管理解決方案

    Navicat?Premium?12是一款跨平臺數(shù)據(jù)庫管理工具,支持MySQL、Oracle等多數(shù)據(jù)庫系統(tǒng),提供數(shù)據(jù)可視化、SQL調(diào)試、版本控制、性能監(jiān)控及安全保護等功能,顯著提升數(shù)據(jù)庫管理效率與團隊協(xié)作能力,下面為大家介紹Navicat?Premium?12數(shù)據(jù)庫管理解決方案,感興趣的朋友一起看看吧
    2025-08-08
  • Spark?SQL小文件問題處理

    Spark?SQL小文件問題處理

    大量的小文件會影響Hadoop集群管理或者Spark在處理數(shù)據(jù)時的穩(wěn)定性,這篇文章主要介紹了Spark?SQL小文件問題的處理,感興趣的同學可以借鑒一下
    2023-04-04
  • Hive日期格式轉(zhuǎn)換方法總結(jié)

    Hive日期格式轉(zhuǎn)換方法總結(jié)

    這篇文章主要為大家介紹了Hive日期格式轉(zhuǎn)換方法總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06

最新評論

中西区| 龙岩市| 德保县| 定兴县| 大冶市| 西宁市| 井陉县| 乌拉特后旗| 贵定县| 甘泉县| 积石山| 略阳县| 铜川市| 吴江市| 交口县| 明星| 西藏| 裕民县| 马龙县| 丹寨县| 钟祥市| 铅山县| 平和县| 河北区| 宁明县| 三门县| 乌兰浩特市| 台东县| 临高县| 白城市| 博乐市| 日照市| 图们市| 吉木萨尔县| 永福县| 安泽县| 安陆市| 阳城县| 揭西县| 前郭尔| 建宁县|