MySQL 会对 sql 语句做优化,
- in 后面的条件不超过一定数量仍然会使用索引。mysql 会根据索引长度和 in 后面条件数量判断是否使用索引。
- 如果是 in 后面是子查询,则不会使用索引。此时采用
join来替换 - 使用
union all代替in和or
使用union all优化的样例
一个文章库,里面有两个表:category 和 article。category 里面有 10 条分类数据。article 里面有 20 万条。article 里面有一个”article_category”字段是与 category 里的”category_id”字段相对应的。 article 表里面已经把 article_category 字义为了索引。数据库大小为 1.3G。
问题描述:
执行一个很普通的查询:
1 | Select * FROM `article` Where article_category=11 orDER BY article_id DESC LIMIT 5 |
执行时间大约要 5 秒左右
解决方案:
建一个索引:
1 | create index idx_u on article (article_category,article_id); |
1 | 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 秒。
使用 OR:
1 | select * from article |
执行时间:11.0777
解决方案:
避免使用 in 或者 or (or 会导致扫表),使用 union all
使用 UNION ALL:
1 | (select * from article where article_category=2 order by article_id desc limit 5) |
执行时间:0.0261