1、業(yè)務邏輯及表介紹
數(shù)據(jù)庫表介紹:
table_a:主表(小表,表數(shù)據(jù)不可重復)
table_b:流水表(大表,記錄審核流水數(shù)據(jù))
注:兩表表結(jié)構(gòu)大致一致,流水表增加一個審核狀態(tài)的字段
業(yè)務邏輯:
主表保存唯一數(shù)據(jù),流水表記錄審核流水數(shù)據(jù),用于后續(xù)展示,并在審核成功后插入主表,在插入流水數(shù)據(jù)時完成重復數(shù)據(jù)的覆蓋。覆蓋邏輯為先刪后加,也就是在這里,出現(xiàn)了聯(lián)表刪除慢的問題。
2、優(yōu)化思路
原聯(lián)表刪除SQL語句 :
delete from table_a where id in (SELECT id FROM table_b );
優(yōu)化后的聯(lián)表刪除SQL語句(懶得繼續(xù)看的,到這即可) :
delete from table_a where exists (SELECT t.id from (select a.id from table_a a,table_b b where a.id=b.id) t where a.id=table_a.id);
3、優(yōu)化原理:
本次優(yōu)化總結(jié)講是將in ==》exists
a、那一定是exists比in語句的效率高嗎?
mysql中的 in 語句是把外表和內(nèi)表作hash 連接,而exists語句是對外表作loop循環(huán),每次loop循環(huán)再對內(nèi)表進行查詢。所以可見,這種說法其實是不準確的。實際是要區(qū)分環(huán)境的:
- 如果查詢的兩個表大小相當,那么用in和exists差別不大。
- 如果兩個表中一個較小,一個是大表,則子查詢表大的用exists,子查詢表小的用in。
- 此外,in與exists的索引使用情況為:in 前表索引,exists 后表索引,用上索引的快。
b、not in 和not exists的比較:
- not in 和not exists如果查詢語句使用了not in 那么內(nèi)外表都進行全表掃描,沒有用到索引;
- not extsts 的子查詢依然能用到表上的索引。
結(jié)論: 無論哪個表大,用not exists都比not in要快
c、in 與 = 的區(qū)別不大
驗證過程略…(感興趣的話自行驗證哈(o-))文章來源:http://www.zghlxwxcb.cn/news/detail-402874.html
4、記錄一個優(yōu)化過程中遇到的問題
sql: delete from table_a where exists (select a.idfrom table_a a,table_b b where a.id=b.id);
報錯: You can’t specify target table ‘table_a’ for update in FROM clause(不能在FROM子句中為更新指定目標表)
解決方法: mysql 可以通過子查詢得到要刪除的記錄條件,然后通過子查詢得結(jié)果匹配要刪除的記錄。但是 mysql 不能直接刪除子查詢表中的數(shù)據(jù),必須通過一個臨時表來解決。文章來源地址http://www.zghlxwxcb.cn/news/detail-402874.html
到了這里,關于MySQL 聯(lián)表查詢重復數(shù)據(jù)并刪除(子查詢刪除記錄) SQL優(yōu)化的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!