sql server 数据分析优化实战(一)——SQL语句优化
前言
在我们进行数据分析的时候,首要的目标是根据业务逻辑,通过编写SQL代码得到我们想要的结果,这是毋庸置疑的。一般情况下,由于我们分析的数据量比较少,体会不出SQL语句各种写法的性能优劣,对SQL代码的优化往往没那么重要。但是随着数据库中数据的增加,尤其是当一个系统需要对海量的数据进行持续性的分析时,SQL的运行效率就成为系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍甚至更多,可见对于数据分析,不是简单地能实现其功能就可,而是要写出高质量的SQL语句,提高系统的可用性和效率。接下来,将介绍几种常用的SQL优化技巧。
WHERE下多个过滤条件的排列顺序
我们在使用WHERE关键字进行条件筛选时,经常会包含多个筛选条件,使用AND进行连接。数据库在对WHERE关键字进行解析时,采用自下而上的顺序进行,即从最后一个过滤条件向前解析。根据这个原理,那些可以过滤掉最大数量记录的条件应该写在WHERE子句的末尾,以减少数据库需要遍历的数据量。例如,我们要从全网3天的KPI数据中筛选出一个站一天的数据。显然,先筛选基站能尽快滤掉更多的数据。因此,我们应把基站筛选放在后面,写成:
重复记录的处理
在我们进行关联操作时,关联条件字段的异常重复数据是影响运行效率和数据质量的一个重要因素。比如我们要根据enb_id字段关联的两张表,这两张表中各有一千条数据的enb_id值为1(这是很常见的错误)。关联后,重复字段的条目数就变为1000*1000。如果重复字段再多,数据量的指数级增长将极大影响运行效率。因此我们需要对数据进行去重处理。以下介绍一种最高效的删除重复记录的方法:
当然,要在熟悉业务逻辑的情况下进行去重,以免误删正常的重复数据。
WHERE、HAVING和ON的比较
WHERE和HAVING关键字都可以对查询结果进行筛选,两者的区别是WHERE的作用时间是在计算之前就完成的,而having是在计算后才起作用的。HAVING只会在检索出所有记录之后才对结果集进行过滤。 这个处理需要排序,总计等操作。显然WHERE能在计算之前滤掉更多数据,效率更高。因此在不涉及计算的筛选中,应尽量使用WHERE。只有对计算之后的字段进行筛选时才考虑使用HAVING。
ON关键字实际上也是对数据进行筛选,只不过是在多表关联时使用。需要注意的是,在我们常用的操作中,表关联是最耗时的操作之一。尤其是两张大表的关联。因此我们应尽量在关联之前对数据进行汇总和筛选,以减少关联的数据量,提高运行效率。例如以下两段代码:
SQL-1:
SQL-2:
第一条SQL的逻辑是先将两表进行关联,再从关联结果中筛选出符合条件的数据。而第二条SQL的逻辑是先从一张表中筛选出需要的数据,再进行关联得到结果。显然第二条SQL需要进行关联的数据量更少,效率更高,尤其是WHERE条件可以滤掉大量数据的情况下。
灵活使用EXISTS关键字
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行连接.在这种情况下,通常我们会考虑使用IN关键字,如:
在这种情况下,使用EXISTS或NOT EXISTS通常是查询效率更高的方法。在子查询中,NOT IN子句将执行一个内部的排序和合并。无论在哪种情况下,NOT IN都是最低效的,因为它对子查询中的表执行了一个全表遍历。为了避免使用NOT IN ,我们可以把它改写成外连接或NOT EXISTS。例如,上面的代码我们可以改写为:
同时,巧妙地使用EXIST还可以更高效地在查询一对多表信息时实现DISTINCT效果。例如,我们要从工参中查询KPI中出现的小区都属于哪些地市。如果使用DISTINCT,实现方法如下:
但DISTINCT是一种很低效的查询方式,应尽量避免使用。我们可以充分利用工参中enb_id唯一的特点使用EXIST更高效地实现同样效果。代码如下:
UNION ALL和UNION
UNION和UNION ALL都有合并数据的效果,但也有细微的区别。UNION ALL只是简单的合并,将重复输出两个结果集合中相同记录,而UNION会去除重复记录。实际上,UNION就是先将两个集合以UNION ALL的方式合并,然后在输出最终结果前进行排序去重。因此UNION效率更低。当我们不需要对结果去重的时候,应尽量使用UNION ALL。
表关联的优化
前面我们分析过,表关联是最耗时间的常用操作之一。因此,表关联优化的一个重要原则就是在关联之前尽量减少两张表格的数据量。看以下两段SQL:
SQL-1:
SQL-2:
思考表连接的的SQL执行顺序,前者两张表JOIN后马上筛选部分结果再与另一张表JOIN,后者先将三张表JOIN后再筛选。所以很明显前者效率比后者高。还有另外一种写法:
第三条和第一条SQL一样效率不错。从逻辑上看,似乎SQL会先将表JOIN后再筛选,但实际结果是先筛选再JOIN。因为SQL SERVER会内部分析,产生一个最优的执行计划,自动处理。而如果按照第二种写法使用JOIN ON的话,就好像是使用强制命令,告诉数据库,就是要按你的方式处理结果,数据库只好服从。
但是有一点需要注意,上面的三种写法使用的都是内关联,三种方法的结果是一样的,只是效率不同。如果使用外关联,结果就有区别了。比如使用LEFT JOIN,第一种写法中,将单表的过滤条件写在ON后面,左表中不符合条件的数据也会被保留,无法起到过滤的作用。而第二种写法先关联再筛选,会滤掉不符合条件的数据。这点需要特别注意,以免发生逻辑上的错误。
后记
最后需要说明一点,如今数据库的类型越来越多,数据库的优化器也越来越智能。很多情况下,数据库的优化器会根据数据情况自动对SQL进行优化。比如,Impala数据库中可使用COMPUTE STATS语句收集表的统计信息,这样在对表进行操作的时候,数据库的优化器就可以自动进行SQL优化。再比如,针对表关联中多表排列顺序的问题,在基于规则的时代,查询效率是和表的连接顺序相关的,小表在左、大表在右的执行效率会高一些。但是现在基本上是基于代价的时代,所以大小表的顺序和效率无关,数据库优化器会自动去进行效率优化。但是,理解数据库内部的代码编译逻辑是数据工程师的基本素质,即使很多时候优化器会帮助我们进行代码优化,使我们减少很多思考,但是良好编程习惯的养成无论在任何时候都能使我们在工作中更加得心应手。
sql server 数据分析优化实战(一)——SQL语句优化的更多相关文章
- SQL Server Cpu 100% 的常见原因及优化
SQL Server Cpu 100% 的情况并不太常见,一般引起 SQL Server 产生性能问题的,都是 阻塞.连接数.IO 磁盘等.所以,一般SQL Server 的使用率都是比较低的.但是, ...
- SQL SERVER 占用资源高的SQL语句
--SQL SERVER 占用资源高的SQL语句: --查询占用cpu高的前 50 个 SQL 语句 SELECT total_cpu_time,[total_physical_Reads], tot ...
- sql server 2008 数据库管理系统使用SQL语句创建登录用户步骤详解
介绍了sql server 2008 数据库管理系统使用SQL语句创建登录用户步骤详解 --服务器角色: --固定服务器角色具有一组固定的权限,并且适用于整个服务器范围. 它们专门用于管理 SQL S ...
- 从零开始学习SQL SERVER(2)--- 基本操作及语句
声明:仅为本人随笔及经验之谈,有错误敬请指出. # 后的文字为注释 Microsoft SQL Server Management Studio 中的SQL命令 添加数据库 1 CREATE DATA ...
- 一名小小的SQL Server DBA想谈一下SQL Server的能力
一名小小的SQL Server DBA想谈一下SQL Server的能力 百度上暂时还没有搜索到相关的个人写的比较有价值的文章,至少在中文网络的世界里面没有 但是在微软的网站有这样一篇文章:<比 ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- 基于iSCSI的SQL Server 2012群集测试(二)--SQL群集安装后初始化配置测试
4.群集安装后初始化配置测试 4.1 禁用full-text 服务和Browser服务 Full-text服务:公司目前暂不使用,需在两个节点上分别禁用 Browser服务:为保证安全,建议将Brow ...
- SQL Server审计功能入门:SQL Server审核 (SQL Server Audit)
原文:SQL Server审计功能入门:SQL Server审核 (SQL Server Audit) 介绍 Audit是SQL Server 2008之后才有的功能,它能告诉你"谁什么时候 ...
- 【转】SQL Server 2008 事件探查器(SQL SERVER Profiler)
跟踪数据库sql语句的执行情况.例:一个系统,用到了sql server 数据库,这个系统共有500张表,当用户在前台页面做某一个操作时,比如插入,登录等等,我们想知道此刻是在对哪一张表操作,打开事件 ...
- SQL Server In-Memory OLTP Internals for SQL Server 2016
SQL Server In-Memory OLTP Internals for SQL Server 2016 这份白皮书是在上一份<SQL Server In-Memory OLTP Inte ...
随机推荐
- Linux 使用pwgen命令创建随机密码
https://blog.csdn.net/fdipzone/article/details/73864598 http://www.netkou.com/?post=155
- MySQL出现:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure Last packet sent to the server was 0 ms ago.
1.首先检查生产环境的机器是否ping的通和telnet的通数据库 2.排查数据库连接的参数 3.看数据量是否很大 参考: http://blog.csdn.net/sclxf/article/det ...
- Memcached启动提示:cann't run as root without the -u switch
如果没有带 -u root 的话就会报: can't run as root without the -u switch 解决方法: 带-u root就行了. 出现的原因: 1.可能在root用户下启 ...
- react 单元测试 (jest+enzyme)
为什么要做单元测试 作为一个前端工程师,我是很想去谢单元测试的,因为每天的需求很多,还要去编写测试代码,感觉时间都不够用了. 不过最近开发了一个比较复杂的项目,让我感觉一旦项目大了.复杂了,而且还是多 ...
- 我的CSDN博客停止更新通告
我的CSDN博客停止更新通告 自从2001年在CSDN发表第一篇博客開始,至今天(2014年6月11日)为止,算起来我己经在CSDN博客上"呆"了13年.共发表251篇原创文章,有 ...
- PLY格式文件具体解释
链接:http://blog.csdn.net/szchtx/article/details/7587999 http://cdu.net.cn/3D/2014-04-23/705.html 一.PL ...
- 模板小程序】求小于等于N范围内的质数
xiaoxi666 联系邮箱: xiaoxi666swap@163.com 博客园 首页 新随笔 联系 订阅 管理 [模板小程序]求小于等于N范围内的质数 1 //筛法求N以内的素数(普通法+优化 ...
- HTTPS那些事 用java实现HTTPS工作原理
HTTPS那些事 用java实现HTTPS工作原理 博客分类: java历险 今天被问到关于https原理的问题,结果由于知识掌握不牢靠,停留于表面,很多细节都无法回答清楚,于是决定把https的 ...
- 放大的X(杭电2565)
/*放大的X 请你编程画一个放大的'X'. Input 输入数据第一行是一个整数T,表示有T组測试数据: 接下来有T行,每行有一个正奇数n(3 <= n <= 79).表示放大的规格. O ...
- 【总结】设备树对platform平台设备驱动带来的变化(史上最强分析)【转】
本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/74375086 版权声明:本文为博主原创文章,转载请注明http://blog.c ...