数据库性能优化是一个很大的话题,因为影响性能的原因有很多,可能是服务器硬件的问题,比如内存、CPU或者网络带宽,也可能是数据库系统的配置不够合理,或者是数据库结构的设计,最后就是写的SQL语句不够高效。今天就一起来看下如何编写高效的SQL语句。
想要使SQL代码更高效,需要对SQL的语法行为有更深入的了解,才能根据不同的情况修改SQL语句的编写方式,从而达到数据库中生成的执行计划(数据库在执行SQL语句前,会先生成执行计划,好比生成很多种路线,然后选择一种最快到达目的地的)更加准确和高效的目的。
请看下面两句SQL:
1. SELECT COUNT(1) FROM dbo.Orders
2. WHERE CustomerCity LIKE '江苏省苏州市%';
3. SELECT COUNT(1) FROM dbo.Orders
4. WHERE LEFT(CustomerCity, 6) = '江苏省苏州市';
这两条语句的目的是一样的,都是获取“江苏省苏州市”的客户订单数,返回的结果也是一样的:

虽然执行返回的结果是相同的,但是他们的执行成本却有差异(在SQL SERVER的管理工具中点开执行计划可以看到下图):

第一个查询使用了45%的开销,而第二个查询则使用了55%的查询成本。实际上,因为我这张表是刚新建的,同时数据又比较规整,如果在正式生产环境下,第二个查询花费的成本会更高。也就是说,在这种情况下,第一个查询语句性能更高。为什么第二个SQL更慢呢?因为它在过滤条件字段上加了一个LEFT函数,假设数据有1千条,那么这个函数就要被执行一千次。非必要情况不要在过滤字段上套函数。
上面只是一个简单的例子,不同类型的SQL语句达到高效时有不同的注意事项,比如对于常见的select查询语句,首先需要知道,select语法有以下几部分组成:
- 查询的数据来自什么表
- 需要查询该表中的什么字段
- 需要查出符合哪些条件的数据
- 对数据进行排序、汇总等操作
在编写SQL语句前,应充分了解查询语句的意图,同时还需了解查询的字段以及查出哪些符合条件的数据。进一步想想这些被检索出来的数据是仅供查询还是需要做一些特殊的汇总计算?
清楚了上述目的后,对提升select语句性能就有了以下几点:
1.只查询出需要的字段
应避免使用select *这样的语句,只查询出需要的字段,避免不必要的I/O。
2.限定好查询出的结果集
写查询语句时,需要注意最终可能返回结果集的大小。当结果集较大时,就应考虑是否可以限定结果集大小(例如使用TOP或者LIMIT语句)或对数据进行分页处理。限定结果集可以避免大批量数据的操作。
3.要有效地使用索引
当需要对数据进行过滤时,应优先考虑使用索引字段。若有多个索引字段可供选择,优先选择重复率比较低的索引字段作为过滤条件。
一般会选择将数据重复率低于5%的字段作为索引过滤字段。不要在过滤字段上使用任何的计算,包括函数、逻辑计算等,因为这些计算公式的加入,将造成查询优化器无法使用相应字段的索引。还有其它可能使索引失效的情况,在排序的时候,应尽量使用有索引的字段进行排序,可以降低排序操作带来的成本开销。
4.关联的表数不要太多
当要查询的信息分散在多张表中时,我们需要联表查询,表关联时关联条件一定要选择正确,关联条件的缺失或是不当很容易造成查询笛卡尔积,从而导致数据量呈几何倍增加。
一条SQL中关联的表最好不要超过5个,对于一个又臭又长的SQL,要么是一开始表结构设计的不合理,要么就是写的有问题,不妨试试将其拆分一下,性能可能会有所改善。
5.小表驱动大表
对于联表查询,比如有A,B,C三张表,分别是1千行、10万行和30万行数据,在join的时候,以A,B,C的顺序进行关联会比C,B,A的顺序更加高效。可以理解成双层循环:一般建议,将数据小的循环放外层。数据大的循环放内层,这样程序的性能会更高。
黑客&网络安全如何学习
如果你也对网路安全技术感兴趣,但是又没有合适的学习资源,我可以把私藏的网安学习资料免费共享给你们,来看看有哪些东西。
网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我们和网安大厂360共同研发的的网安视频教程,内容涵盖了入门必备的操作系统、计算机网络和编程语言等初级知识,而且包含了中级的各种渗透技术,并且还有后期的CTF对抗、区块链安全等高阶技术。总共200多节视频,100多本网安电子书,最新学习路线图和工具安装包都有,不用担心学不全。



被折叠的 条评论
为什么被折叠?



