MySQL not exists 的優化


現有2張表 商品表和 用戶購買記錄表

create table dr_purchased
(
  id           bigint auto_increment
    primary key,
  user_id      bigint                                  not null comment '用戶ID dr_user表ID',
  product_type int                                     not null comment '商品類型',
  product_id   bigint                                  not null comment '產品ID dr_product表ID',
  goods_id     int                                     not null comment '商品ID',
  expire_time  timestamp default '2000-01-01 00:00:00' null comment '產品過期時間',
  platform_id  int                                     null comment '平台類型 1:ios 2:安卓'
)

 

create table dr_product
(
  id           bigint auto_increment comment '商品ID'
    primary key,
  code         varchar(64)  default ''                not null comment '商品編碼-IOS應用商店需要這個碼',
  name         varchar(200) default ''                not null comment '產品名稱',
  type         int          default 0                 not null comment '商品類型',
  goods_id     int          default 0                 not null comment '商品ID',
  price        int                                    not null comment '售價',
  origin_price int                                    null comment '原價',
  sales_volume int          default 0                 null comment '銷量',
  remarks      varchar(255) default ''                not null comment '備注',
  online       int          default 1                 not null comment '是否在用'
)
  comment '商品表';

 

現在有一個需求是查找用戶未購買的商品, 一般我們會寫出這樣的查詢

select *
from dr_product t
where not exists(select product_id
                 from dr_purchased p
                 where p.user_id = ? 
                   and t.id = p.product_id)

 

現在我們看一下explain

 

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t NULL ALL NULL NULL NULL NULL 92 100 Using where
2 DEPENDENT SUBQUERY p NULL ref dr_purchased_user_id_product_type_goods_id_index dr_purchased_user_id_product_type_goods_id_index 8 const 25 10 Using where

我們可以看到type為ref確實是使用了索引,但是我們用另外一種寫法來試一試。

explain select * from
  dr_product t left join dr_purchased p on
p.user_id=? and  t.id=product_id
where p.id is null;

 

id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t NULL ALL NULL NULL NULL NULL 92 100 NULL
1 SIMPLE p NULL ref dr_purchased_user_id_product_type_goods_id_index dr_purchased_user_id_product_type_goods_id_index 8 const 25 10 Using where; Not exists

 

我們可以看到執行計划沒有什么本質的區別。但是經過測試 連接查詢效率更好。

最后重要的事情要再提一遍,SQL優化,一定要具體問題具體分析,沒有萬能的解決方案


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM