1. 程式人生 > >【mysql優化】語句優化

【mysql優化】語句優化

src inf lai 是否 color clas plain sel 連接

技術分享圖片

1.int型子查詢陷阱

: 在ecshop商城表中,查詢6號欄目的商品, (註,6號是一個大欄目)

  最直觀的: mysql> select goods_id,cat_id,goods_name from goods where cat_id in (select cat_id from ecs_category where parent_id=6);

誤區: 給我們的感覺是, 先查到內層的6號欄目的子欄目,如7,8,9,11

  然後外層, cat_id in (7,8,9,11)

事實: 如下圖, goods表全掃描, 並逐行與category表對照,看parent_id=6是否成立

技術分享圖片

原因: mysql的查詢優化器,針對In型做優化,被改成了exists的執行效果.

  當goods表越大時, 查詢速度越慢.

總結:in 查詢不是我們想的那樣,而是逐行掃描外層的數據去匹配裏面,因此查詢效率低下。

改進: 用連接查詢來代替子查詢

explain select goods_id,g.cat_id,g.goods_name from goods as g

inner join (select cat_id from ecs_category where parent_id=6) as t

using(cat_id) \G

內層 select cat_id from ecs_category where parent_id=6 ; 用到Parent_id索引, 返回4行

2 exists子查詢

題: 查詢有商品的欄目.

按上面的理解,我們用join來操作,如下:

mysql> select c.cat_id,cat_name from ecs_category as c inner join goods as g

on c.cat_id=g.cat_id group by cat_name;

 

3.優化規則:

優化1: 在group時, 用帶有索引的列來group, 速度會稍快一些,另外,

int型 比 char型 分組,也要快一些.

優化2: 在group時, 我們假設只取了A表的內容,group by 的列,盡量用A表的列,會比B表的列要快.

優化3: 從語義上去優化

select cat_id,cat_name from ecs_category where exists(select *from goods where goods.cat_id=ecs_category.cat_id)

優化4:

from 型子查詢:

  註意::內層from語句查到的臨時表, 是沒有索引的.所以: from的返回內容要盡量少.

【mysql優化】語句優化