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的返回内容要尽量少.

in型子查询陷阱,exists子查询的更多相关文章

  1. mysql优化---in型子查询,exists子查询,from 型子查询

    in型子查询引出的陷阱:(扫更少的行,不要临时表,不要文件排序就快) 题: 在ecshop商城表中,查询6号栏目的商品, (注,6号是一个大栏目) 最直观的: mysql); 误区: 给我们的感觉是, ...

  2. mysql---where子查询、form子查询、exists子查询

    1.什么是子查询? 当一个查询是另一个查询的条件时,称之为子查询. 2.子查询有什么好处? 子查询可以使用几个简单命令构造功能强大的复合命令. 那么,现在让我们一起来学习子查询. 3.where型的子 ...

  3. 7-14 EXISTS子查询

    EXISTS: 只注重于子查询是否有返回行,如果查有返回行返回结果为值,否则为假 并不使用子查询的结果,仅用于测试子查询是否有返回结果. 语法: IF EXISTS (子查询) BEGIN 语句块 E ...

  4. java数据库编程之嵌套子查询及exists的使用

    第四章:高级查询(二) 4.1:exists和not exists子查询 4.1.1:exists子查询 用exists作为子查询的where条件 语法:select,,,,,,from 表名   w ...

  5. 关于T-SQL中exists或者not exists子查询的“伪优化”的做法

    问题起源 在使用t-sql中的exists(或者not exists)子查询的时候,不知道什么时候开始,发现一小部分人存在一种“伪优化”的一些做法,并且向不明真相的群众传递这一种写法“优越性”,实在看 ...

  6. JOIN与EXISTS(子查询)的效率研究

    使用MySQL提供的Sample数据库Sakila 现将profiling打开,用来一会查看sql执行时间 set profiling=1; exists 子查询与 join联接效率的对比,功能:查看 ...

  7. 子查询及exists

    子查询分为无关子查询和相关子查询 无关子查询,只查询一次,与外查询无关,可作为查询条件: select * from student where sno in (select sno from stu ...

  8. sql server 子查询 和exists使用

    概述 子查询的概念: 当一个查询是另一个查询的条件时,称之为子查询.子查询可以嵌套在主查询中所有位置,包括SELECT.FROM.WHERE.GROUP BY.HAVING.ORDER BY. 外面的 ...

  9. Mysql常用sql语句(19)- in / exists 子查询

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 子查询在我们查询方法中是比较常用的,通过子查询可 ...

随机推荐

  1. SpringBoot使用MyBatis报错:Error invoking SqlProvider method (tk.mybatis.mapper.provider.base.BaseInsertProvider.dynamicSQL)

    © 版权声明:本文为博主原创文章,转载请注明出处  1. 错误描述 使用SpringBoot集成MyBatis框架,并且使用 mapper-spring-boot-starter 自动生成MyBati ...

  2. Django--登录认证

    COOKIE 与 SESSION 概念 cookie的使用,不止局限于我们所使用的登录认证,cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此 ...

  3. iOS tableView Section圆角方案

    给tableView的section设置圆角 首先给让cell左右偏移一点的距离,通过重写cell的setframe方法来实现 -(void)setFrame:(CGRect)frame{ CGFlo ...

  4. MVC进阶学习--View和Controller之间的数据传递(一)

    1.使用ViewData ViewData 的是ControllerBase 的一个属性,是一个数据字典类型的,其实现代码如(这段代码来自asp.net MVC开源项目中源码)下: Code   1  ...

  5. 第1章列表处理——1.1 Lisp列表

    Lisp是啥? Lots of Isolated Silly Parentheses (大量分离的愚蠢的括号) Lisp指的是"LISt Processing"(列表处理),通过把 ...

  6. ngnix 参考配置

    #user nobody; worker_processes ; #error_log logs/error.log; #error_log logs/error.log notice; #error ...

  7. JS中关于闭包和this的指向

    闭包个人理解   函数内部还有一个函数,其作用就是可以访问上一层函数中的变量 下面的案例中函数内部有函数,this的指向就变为window了 结果闭包中this指向的两种方法 1.call对象冒充可以 ...

  8. ural 1303 Minimal Coverage【贪心】

    链接: http://acm.timus.ru/problem.aspx?space=1&num=1303 http://acm.hust.edu.cn/vjudge/contest/view ...

  9. Python学习笔记_Python基础

    Python 基础 语句和语法 凝视 继续 代码组 代码的缩进 在一行书写多个语句 模块 变量赋值 赋值操作符 增量赋值 多重赋值 多元赋值 python编写的基本风格 模块的结构和布局 内存管理 变 ...

  10. Js中的Object.defineProperty

    通过Object.defineProperty为对象设置属性,并同时规定属性的属性(可见性,可配置性,可枚举性等) 备注:如果通过var obj = {} obj.age = 18这种方式设置的属性, ...