Ø 简单的性能优化
Sql的性能优化是数据库工程师在实际工作中必须面对的重要课题之一。对于某些数据库工程师来说,它几乎唯一的命题。实际上,像WEB服务这样需要快速响应的应用场景中,SQL的性能直接决定了系统是否可以使用。这里主要介绍一些使用SQL执行速度更快,消耗内存更少的优化技巧,今天的文章只介绍其中的一种,后续会继续更新一些其它的优化方式。
严格地优化查询性能时,必须要了解所使用的数据库的功能特点。此外,查询速度慢并不只是因为SQL语句本身,还可能是因为内存分配不佳,文件结构不合理等其他原因。因此这里介绍的优化SQL的方法未必能解决所有的性能问题,但是确实很多时候的查询性能不好的原因还是SQL的写法不合理。
Ø 使用高效的查询
在SQL中,很多时候不同代码能够得到相同的结果。从理论上来说,得到相同结果的不同代码应该有相同的性能,但遗憾的是,查询优化器生成的执行计划很大程度要受到代码外部结构的影响。因此如果想优化查询性能,必须知道如何写代码才能使优化器的执行效率更高。
参数是子查询时,使用EXISTS代替IN
IN谓词非常方便,而且代码容易理解,所以使用的频率很高。但是方便的同时,IN谓词却有成为性能优化的瓶颈的危险。如果代码中大量用到IN谓词,那么一般只对它们进行优化就能大幅度地提升性能。
如果IN的参数是“1,2,3”这样的数值列表,一般还不需要特别注意。但是如果参数是子查询,那么就需要注意了。
大多数情况,[NOT]IN和[NOT]EXISTS返回的结果是相同的。但是两者用于子查询时,EXISTS的速度会更快一些。
下面来看个例子:
我们试着从Class_A表中查出同时存在于Class_B表中的员工。下面两条SQL语句返回的结果是一样的,但是使用EXISTS的SQL语句更快一些。
两个结果都如下所示:
使用EXISTS时更快的原因有以下两个。
a) 如果连接列(id)上建立了索引,那么查询Class_B时不用查询实际的表,只需查索引就可以了。
b) 如果使用EXISTS,那么只要查到一行数据满足条件就会终止查询,不用像使用IN时一样扫描全表。在这一点上NOT EXISTS也一样。
当IN的参数是子查询时,数据库首先会执行子查询,然后将结果存储在一张临时的工作表里(内联视图),然后扫描整个视图。很多情况下这种做法都非常耗费资源。使用EXISTS的话,数据库不会生成临时的工作表。
但是从代码的可读性上来看,IN要比EXISTS好。使用IN时的代码看起来更一目了然,易于理解。因此,如果确信使用IN也能快速获取结果,就没有必要非得改成EXISTS了。
而且,最近有很多数据库也尝试着改善了IN的性能。也许未来的某一天,无论哪个数据库上,IN都能具体和EXISTS一样的性能。
参数是子查询时,使用连接代替IN
要想改善IN的性能,除了使用EXISTS,还可以使用连接。前面的查询语句就可以像下面这样“扁平化”。
这种写法至少能用到一张表的“id”列上的索引。而且,因为没有了子查询,所以数据库也不会生成中间表。我们很难说与EXISTS相比哪个更好,但是如果没有索引,那么与连接相比,可能EXISTS会略胜一筹。而且从很多查询可以看出,有些情况下使用EXISTS比使用连接更合适。
原文链接:https://www.cnblogs.com/cldmxw/p/10483387.html