join查询内使用where过滤与join查询内不使用where过滤
来源:互联网 发布:ubuntu 16.04更改 英文 编辑:程序博客网 时间:2024/04/28 19:09
I、建表(id不为主键或者索引)
一、首先建表
1. myorder
CREATETABLE `myorder` (
`id` int(10) NOT NULL,
`order_name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf-8 COMMENT='订单表';
2. myorderdetail
CREATETABLE `myorderdetail` (
`id` int(10) NOT NULL,
`oid` int(10) DEFAULT NULL,
`product_name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf-8 COMMENT='订单商品表';
二、分别在表1和表2插入1K,27W数据,使用到存储过程
BatchInsert(IN init INT, IN loop_time INT)
建存储过程语句:
CREATE DEFINER=`root`@`localhost` PROCEDURE `BatchInsert`(INinit INT, IN loop_time INT)
BEGIN
DECLARE Var INT;
DECLARE ID INT;
DECLARE OID int;
SET Var = 0;
SET ID = init;
SET OID =init;
WHILE Var < loop_time DO
insert into 表名(字段1,字段2,…) values(字段1值,字段2值,…);
SET ID = ID + 1;
SET OID = OID + 1;
SET Var = Var + 1;
END WHILE;
END
三、业务逻辑
查询出myorder里在myorderdetail 里有的订单的记录,其中myorderdetail 的id需要在id>100 and id<270000。
a.直接join(join内不使用where过滤myorderdetail)
SELECT * FROM myorder a JOIN myorderdetailb ON a.id = b.oid
WHERE b.id > 100 AND b.id < 270000
此时的查询时间19.21s
b. 在join时候在join子句中使用where 过滤
SELECT * FROM myorder a JOIN(
SELECT * FROM myorderdetail WHERE id > 100 AND id < 270000
) b ON a.id = b.oid
此时查询耗时 1.674s
所以:
由19.21s>1.67s,因此在join之前给予join先过滤是很有必要的。
II、更改二表的id为主键(唯一索引)
Sql:
ALTER TABLE ` 表名` ADDPRIMARY KEY ( `id` )
1.a.直接join(join内不使用where过滤myorderdetail)
SELECT * FROM myorder a JOIN myorderdetailb ON a.id = b.oid
WHERE b.id > 100 AND b.id < 270000
此时的查询时间 0.982s(之前19.21s)
b. 在join时候在join子句中使用where 过滤
SELECT * FROM myorder a JOIN(
SELECT * FROM myorderdetail WHERE id > 100 AND id < 270000
) b ON a.id = b.oid
此时查询耗时 1.617s(之前1.674s)
III.更改2表的id为普通索引
1.a.直接join(join内不使用where过滤myorderdetail)
SELECT * FROM myorder a JOIN myorderdetail b ON a.id = b.oid
WHERE b.id > 100AND b.id < 270000
此时的查询时间 0.571s(之前19.21s)
b. 在join时候在join子句中使用where 过滤
SELECT * FROM myorder a JOIN(
SELECT * FROM myorderdetail WHERE id > 100 AND id < 270000
) b ON a.id = b.oid
此时查询耗时 1.746(之前1.674s)
总结:
主键(唯一索引)VS普通字段作为筛选条件
0.982sVS 19.21s(不在join里筛选查询)
1.617sVS 1.674s(在join里筛选查询)
普通索引VS普通字段作为筛选条件
0.571sVS 19.21s(不在join里筛选查询)
1.746s VS1.674s(在join里筛选查询)
结论:
1.在关联条件不是主键或者索引的情况下,join语句还是要先筛选(在被join的表里where过滤)再join其他表。
2.在关联条件是主键或者索引的情况下,被join的表不需要被筛选(在被join的表里where过滤)再join其他表。
就本项目给予建议:
1.sql中尽量少使用子查询(opentable需要时间长)
2.根据项目实际情况
a.需要连接的字段上建索引,再单纯join
b.如果连接字段因为某些原因没建索引,则需要在join时候先筛选在join(即子查询),此时sql看起来长些,但效率会好很多。
原因如下:
join里面子查询和普通join的explain执行计划比较可知道二这差距主要集中在opentables,差距比较大。
- join查询内使用where过滤与join查询内不使用where过滤
- 从数据库中随机查询记录,使用JOIN比使用WHERE的效率要好
- left join 与where
- 数据库连接查询使用and与where区别
- mysql中join使用on、where范围
- DataTable中使用Order By排序与Where过滤 实例
- mysql left( right ) join使用on 与where 筛选的差异 博客分类: mysql MySQLSQL数据结构 有这样的一个问题mysql查询使用mysql中left(
- 内连接查询 (select * from a join b on a.id = b.id) 与 关联查询 (select * from a , b where a.id = b.id)的区别
- hibernate使用@where实现条件过滤功能
- 使用where子句过滤表中数据
- [My SQL] 使用WHERE过滤数据
- JOIN ON后面的过滤条件和where后面的过滤条件有什么不同?
- hive表在join on上的过滤和在where上过滤的对比
- 数据库多表查询之 where & INNER JOIN
- 数据库多表查询之 where & INNER JOIN
- 数据库多表查询之 where & INNER JOIN
- 数据库多表查询之 where & INNER JOIN
- 数据库多表查询之 where & INNER JOIN
- Vlan学习笔记终极整理
- Spring整合Hibernate的时候使用hibernate.cfg.xml
- 比较字符串strcmp()函数
- 试用vSphere 6(六):VCSA(6.0.0.2175370)的安装与配置
- ODBC测试成功,调用失败的问题。
- join查询内使用where过滤与join查询内不使用where过滤
- 自己写的一个tomcat发布脚本
- JSON简介及常用操作
- Swift中使用随机数
- 当Eclipse爱上SVN
- 安全模式或开发者模式动画程序关闭动画时长缩放,动画最好不要执行
- 常用Mysql命令
- [javase学习笔记]-8.1 static关键字之特点
- 指针加减与地址强制转化