MySQL NOT EXISTS優化的乙個案例

2021-07-26 22:00:02 字數 1850 閱讀 9788

exists是對外表作loop迴圈,每次loop迴圈再對內表進行查詢,在專案中遇到類似的問題,資料量大時,not exists不管用並且執行sql的時間很長,

在網上查了一些資料,所以記錄下來:

原始sql:

explain select relation.id,relation.invited_code,relation.uid,relation.create_time,relation.invited_uid from tran_user_invited_relation relation,  

tran_user user where 1=1 and user.uid=relation.uid and user.register_time>='2017-01-01 19:40:09' and user.register_time<='2017-12-15 16:33:49' and

not exists (select 1 from tran_user_reward reward where reward.sources='invite_auth' and reward.invited_relation_id=relation.id)

關於優化把以上sql修改一下做幾點思考: 

對於原始語句,因為是not exists判斷,所以子查詢中沒有必要select * from dual,只需select id甚至是select 1都可以。

另外,鑑於mysql子查詢演算法效能較差,考慮改寫成對應的join方式,因為這裡是not exist判斷,所以改寫時有一定技巧,

即可使用左連線,然後過濾出未能連線的記錄做乙個條件篩選得到想要的資料。還有,原始語句最外層的查詢也是select 至於這個是否有必要應當依據具體業務,

盡量在滿足業務要求的條件下取盡可能少的字段。最後,即時做了上述優化,若在連線條件上沒有合適的索引sql效能仍然會非常差(特別是在表的資料量巨大的時候),

所以考慮在連線的條件列reward.invited_relation_id和relation.id上分別建立索引。

優化後的sql是:

sql由原來的30s的執行時間減少到1-2左右秒內。

explain select invited.id,invited.invited_code,invited.uid,invited.create_time,invited.invited_uid from (

(select user.uid from tran_user user where 1=1 and user.rna_status=1 and user.register_time>='2017-01-01 19:40:09'

and user.register_time<='2017-12-15 16:33:49') as `user` left join

(select invited.id,invited.invited_code,invited.uid,invited.create_time,invited.invited_uid from

tran_user_invited_relation invited) as invited on user.uid=invited.uid left join

(select id as rewards_id ,invited_relation_id from tran_user_reward where 1=1 and sources='invite_auth' and invited_relation_id !=0) reward on

invited.id=reward.invited_relation_id ) where reward.rewards_id is null and invited.id is not null

MySQL not exists 真的不走索引麼

在一些業務場景中,會使用not exists語句確保返回資料不存在於特定集合,部分同事會發現not exists有些場景效能較差,甚至有些網上謠言說 not exists不走索引 哪對於not exists語句,我們如何優化呢?以今天優化的sql為例,優化前sql為 select count 1 f...

spark調優 shuffle調優

基於spark1.6 引數可以通過 new sparkcontext set 來設定,也可以通過命令的引數設定 conf spark.shuffle.file.buffer 預設值 32k 引數說明 該引數用於設定shuffle write task的bufferedoutputstream的buf...

Spark Spark調優 資源調優

spark在乙個executor的記憶體分為三塊,1.一塊是execution記憶體 2.一塊是storge 記憶體 3.一塊是其他記憶體 執行記憶體是執行記憶體,加入,聚合都是在這部分記憶體中執行.shuffle的資料也會先快取在這個記憶體中,滿了再寫入磁碟,能減少io,其實地圖過程也是在這個記憶...