SQL学习—优化SQL查询性能
2019-01-23 18:04
225 查看
1-11 让SQL飞起来
使用高效的查询
参数是子查询时,使用EXISTS代替IN。
两个代码对比:
--慢 SELECT * FROM Class_A WHERE id IN (SELECT id FROM Class_B)
--快 SELECT * FROM Class_A WHERE EXISTS( SELECT * FROM Class_B WHERE A.id = B.id)
原因:
- 如果连接列(id)上建立了索引,那么查询Class_B时不要查实际的表,只需查索引就可以了。
- 如果使用EXISTS,那么只要查到一行数据满足条件就会终止查询,不用像使用IN时一样扫描全表,这点上NOT EXISTS也一样。
当IN的参数是子查询时,数据库会首先执行子查询,然后将结果存储在一张临时的工作表里(内联视图),然后扫描整个视图。使用EXISTS的话,数据库不会生成临时的工作表。
参数是子查询时,使用连接代替IN。
--使用连接代替IN SELECT A.id, A.name FROM Class_A A INNER JOIN Class_B ON A.id = B.id
这种写法至少用到一张表的"id"列上的索引。而且没有子查询,数据库也不会生成一张中间表。
避免排序
SQL中会进行排序的运算有:
- GROUP BY 子句
- ORDER BY 子句
- 聚合函数(SUM、COUNT、AVG、MAX、MIN)
- DISTINCT
- 集合运算符(UNION、INTERSECT、EXCEPT)
- 窗口函数(RANK、ROW_NUMBER等)
思考:如何从上面的商品表Items中找出同时存在于销售记录表SalesHistory中的商品。换言之,找出有销售记录的商品。
SELECT I.item_no FROM Items I INNER JOIN SalesHistory SH ON I.item_no = SH.item_no
因为是一对多的连接,所以"item_no"列中会出现重复数据。为了排除重复数据,需要使用DISTINCT。
更好的做法是使用EXISTS。
SELECT I.item_no FROM Items I WHERE EXISTS( SELECT * FROM SalesHistory SH WHERE I.item_no = SH.item_no)
在极值函数中使用索引(MAX/MIN)
使用这两个函数时都会进行排序。但是如果参数字段上建有索引,则只需要扫描索引,不需要扫描整个表。
-- 这样写需要扫描全表 SELECT MAX(item) FROM Items
-- 这样写能用到索引 SELECT MAX(item_no) FROM Items
因为item_no是表Items的唯一索引,所以效果更好。
能写在WHERE子句里的条件不要写在HAVING子句里
-- 聚合后使用HAVING子句过滤 SELECT sale_date, SUM(quantity) FROM SalesHistory GROUP BY sale_date HAVING sale_date = '2017-10-01'
--聚合前使用WHERE子句过滤 SELECT sale_date, SUM(quantity) FROM SalesHistory WHERE sale_date = '2017-10-01' GROUP BY sale_date
从性能上看,第二条语句写法效率更高。原因:
- 使用 GROUP BY 子句聚合时会进行排序,如果事先通过WHERE 子句筛选出一部分行,就能够减轻排序的负担。
- WHERE子句的条件里可以使用索引。HAVING子句是针对聚合后生成的视图进行筛选的,但是很多时候聚合后的视图都没有继承原表的索引结构。
在GROUP BY 子句和ORDER BY 子句使用索引
一般来讲,GROUP BY 子句和 ORDER BY 子句都会进行排序,来对行进行排列和替换。不过,通过指定带索引的列作为GROUP BY 和 ORDER BY 的列,可以实现快速查询。
真的用到索引了吗
下面几种否定形式不能用到索引
- <>
- !=
- NOT IN
减少中间表
在 SQL 中,子查询的结果会被看成一张新表,这张新表与原始表一样,可以通过代码进行操作。
- 灵活使用HAVING子句
- 需要对多个字段使用IN谓词时,将它们汇总到一处
- 先连接再进行聚合
SELECT sale_date,MAX(quantity) FROM SalesHistory GROUP BY sale_date HAVING MAX(quantity) >=10
SELECT * FROM Addresses1 A1 WHERE (id,state,city) IN (SELECT id,state,city FROM Addresses2 A2)
相关文章推荐
- Oracle性能优化学习笔记之共享Sql语句
- ORACLE数据库学习之SQL性能优化详解
- SQL 查询性能优化 解决书签查找
- 【SqlServer2005+ 查询优化】MSSQL优化SQL语句 提高数据库的访问性能
- .Net+SQL Server企业应用性能优化笔记3——SQL查询语句
- Oracle性能优化学习笔记之共享Sql语句
- ORACLE数据库学习之SQL性能优化详解
- 通过手动创建统计信息优化sql查询性能案例
- SQL 查询性能优化----解决书签查找
- ORACLE数据库学习之SQL性能优化详解
- SQl语句查询性能优化
- MySQL优化三:查询性能优化之SQL查询执行过程
- 数据库订正脚本性能优化两则:去除不必要的查询和批量插入SQL
- Oracle SQL性能优化系列学习一
- SQL查询性能优化 之 LEFT JOIN 替换 NOT IN
- SQL性能优化中的底层概念,时间复杂度,算法和数据结构,数据库组成,查询优化和表关联原理.
- SQL查询性能优化
- 以淘宝商品搜索漫谈查询条件的排序对效率的影响(SQL查询性能优化,附调优(性能诊断)DMV)
- 索引,Sql查询性能优化,书签查找
- 【MySql性能优化二】利用explain进行查询和分析sql语句