MYSQL索引優化, IN OR 等優化措施
阿新 • • 發佈:2019-01-06
一個文章庫,裡面有兩個表:category和article, category裡面有10條分類資料,article裡面有 20萬條。
執行一個很普通的查詢: select * from article where article_category=11 order by article_id desc limit 5 , 執行時間大約要5秒左右 解決方案:
建一個索引:create index idx_u on article (article_category,article_id);
select * from article where article_category=11
order by article_id desc limit 5 減少到0.0027秒.
又有問題:
1) select * from article`where article_category IN (2, 3) order by article_id desc limit
5, 執行時間要11.2850秒。
2) 換成OR, select * from article where article_category=2 or article_category=3 order by article_id desc limit 5, 執行時間:11.0777
上面這兩個問題的時間基本差不多。
優化方案: 避免使用 in 或者 or ( or會導致掃表),使用 union all 來替換它們,如下:
(select * from article where article_category=2 order by article_id desc limit 5)
UNION ALL (select * from article where article_category=3 order by article_id desc limit
5)
order by article_id desc limit 5
執行時間:0.0261
article裡面有一個"article_category"欄位是與category裡的"category_id"欄位相對應的。
article表裡面已經把 article_category字義為了索引。資料庫大小為1.3G。
問題描述:執行一個很普通的查詢: select * from article where article_category=11 order by article_id desc limit 5 , 執行時間大約要5秒左右 解決方案:
2) 換成OR, select * from article where article_category=2 or article_category=3 order by article_id desc limit 5, 執行時間:11.0777
從效率上說,UNION ALL 要比UNION快很多,所以,如果可以確認合併的兩個結果集中不包含重複資料且不需要排序時的話,那麼就使用UNION ALL
很多時候用 exists 代替 in 是一個好的選擇:select num from a where num in(select num from b)
用下面的語句替換:
select num from a where exists ( select num from b where num = a.num )