Java教程之SQL性能优化提升

  Ø 简单的性能优化

  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

        

千锋<a href=http://www.mobiletrain.org/ target=_blank class=

Java培训.png" width="153" height="118" style="border-width: initial; border-style: none; vertical-align: top; display: inline-block;">     

千锋<a href=http://www.mobiletrain.org/ target=_blank class=

Java培训.png" width="153" height="118" style="border-width: initial; border-style: none; vertical-align: top; display: inline-block;">

  我们试着从Class_A表中查出同时存在于Class_B表中的员工。下面两条SQL语句返回的结果是一样的,但是使用EXISTS的SQL语句更快一些。

千锋<a href=http://www.mobiletrain.org/ target=_blank class=

Java培训.png" width="398" height="151" style="border-width: initial; border-style: none; vertical-align: top; display: inline-block;">

千锋<a href=http://www.mobiletrain.org/ target=_blank class=

Java培训.png" width="578" height="187" style="border-width: initial; border-style: none; vertical-align: top; display: inline-block;">

  两个结果都如下所示:

千锋<a href=http://www.mobiletrain.org/ target=_blank class=

Java培训.png" width="235" height="102" style="border-width: initial; border-style: none; vertical-align: top; display: inline-block;">

  使用EXISTS时更快的原因有以下两个。

  a) 如果连接列(id)上建立了索引,那么查询Class_B时不用查询实际的表,只需查索引就可以了。

  b) 如果使用EXISTS,那么只要查到一行数据满足条件就会终止查询,不用像使用IN时一样扫描全表。在这一点上NOT EXISTS也一样。

  当IN的参数是子查询时,数据库首先会执行子查询,然后将结果存储在一张临时的工作表里(内联视图),然后扫描整个视图。很多情况下这种做法都非常耗费资源。使用EXISTS的话,数据库不会生成临时的工作表。

  但是从代码的可读性上来看,IN要比EXISTS好。使用IN时的代码看起来更一目了然,易于理解。因此,如果确信使用IN也能快速获取结果,就没有必要非得改成EXISTS了。

  而且,最近有很多数据库也尝试着改善了IN的性能。也许未来的某一天,无论哪个数据库上,IN都能具体和EXISTS一样的性能。

  参数是子查询时,使用连接代替IN

  要想改善IN的性能,除了使用EXISTS,还可以使用连接。前面的查询语句就可以像下面这样“扁平化”。

千锋<a href=http://www.mobiletrain.org/ target=_blank class=

Java培训.png" width="515" height="129" style="border-width: initial; border-style: none; vertical-align: top; display: inline-block;">

  这种写法至少能用到一张表的“id”列上的索引。而且,因为没有了子查询,所以数据库也不会生成中间表。我们很难说与EXISTS相比哪个更好,但是如果没有索引,那么与连接相比,可能EXISTS会略胜一筹。而且从很多查询可以看出,有些情况下使用EXISTS比使用连接更合适。

  千锋成都Java培训作为国内IT研发人才一体化服务的开拓者,为学生制定合理有序的学习计划,0学费入学,2周免费试听不满意不收费,与学员签订就业协议,坚持良心面授,从千锋Java培训班出去的学员均已高薪就业。千锋推出的免费java视频教程,让学员能够方面的巩固基础技术能力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值