in 型子查询引出的陷阱 select goods_id from goods where cat_id in (1,2,3) 直接用id,不包含子查询,不会中陷阱

题: 在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表越大时, 查询速度越慢.

select goods_id,cat_id,goods_name from  goods where cat_id in (select cat_id from ecs_category where parent_id=6)

改进: 用连接查询来代替子查询

 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

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; (见36)

优化1:  在group时, 用带有索引的列来group, 速度会稍快一些,另外,

用int型 比 char型 分组,也要快一些.(见37)

优化2: 在group时, 我们假设只取了A表的内容,group by 的列,尽量用A表的列,

会比B表的列要快.(见38)

优化3: 从语义上去优化

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

|       36 | 0.00039075 | 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

|

|       37 | 0.00038675 | 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_id

|

|       38 | 0.00035650 | 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 c.cat_id

|

|       40 | 0.00033500 | select cat_id,cat_name from ecs_category where exists

(select * from  goods where  goods.cat_id=ecs_category.cat_id)

|

from 型子查询:

注意::内层from语句查到的临时表, 是没有索引的. select id from (select id from t1 where cat_id=100) where id>100  其中id>100是没有索引的,from的是一个临时表

所以: from的返回内容要尽量少.

最新文章

  1. 在开启DRS的集群中修复VMware虚拟主机启动问题
  2. 如何开发一个Jquery插件
  3. jeffy-vim-v3.0
  4. github-提交仓库
  5. 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
  6. Virtualbox中不能为虚拟机打开一个新任务的原因及解决方法
  7. SQL NOT EXISTS
  8. 把java对象转化为json格式的对象数组
  9. Serializer序列化/反序列化DateTime少了8小时问题解决
  10. Python学习教程(learning Python)--2.3.2 Python函数实参详解
  11. ubuntu12.10升级至14.04
  12. 递归函数recursion
  13. java.io.FileNotFoundException: /exapp/hadoop/name/current/VERSION (Permission denied)
  14. IE6双倍margin间距解决方法
  15. 201521123096《Java程序设计》第一周学习总结
  16. jQuery 捕获
  17. maven私服nexus清理释放磁盘空间
  18. DirectX11--实现一个3D魔方(2)
  19. [物理学与PDEs]第1章第7节 媒质中的 Maxwell 方程组 7.2 媒质交界面上的条件
  20. Linux 驱动——Button驱动7(Timer)消抖

热门文章

  1. python测试网页是否能正常登陆
  2. 在Mac上为自己手动编译安装一套PHP7的开发环境
  3. linux下的Java开发 intellij idea+tomcat+maven
  4. Smart pointer 智能指针小总结
  5. Photoshop经常使用快捷键(2)
  6. error items-9022:missing required icon file.the bundle does not contain an app icon for iPhone/iPad Touch of exactly '120x120' pixels,in.pen format for ios versions >= 7.0
  7. [Java开发之路](8)输入流和输出流
  8. 承载(Host)通用语言执行时
  9. Zipper (DP)
  10. Frobenius Norm