优化 SQL SELECT 语句性能的 6 个简单技巧

SELECT语句的性能调优有时是一个非常耗时的任务,在我看来它遵循帕累托原则。20%的努力很可能会给你带来80%的性能提升,而为了获得另外20%的性能提升你可能需要花费80%的时间。除非你在金星工作,那里的每一天都等于地球上的243天,否则交付期限很有可能使你没有足够的时间来调优SQL查询。

根据我多年编写和运行SQL语句的经验,我开始开发一个检查列表,当我试图提高查询性能时供我参考。在进行查询计划和阅读我使用的数据库文档之前,我会参考其中的内容,数据库文档有时会很复杂。我的检查列表绝对说不上全面或科学,它更像是一个保守计算,但我可以说,遵循这些简单的步骤大部分时间我确实能得到性能提升。检查列表如下。

检查索引

在SQL语句的WHERE和JOIN部分中用到的所有字段上,都应该加上索引。进行这个3分钟SQL性能测试。不管你的成绩如何,一定要阅读那些带有信息的结果。

限制工作数据集的大小

检查那些SELECT语句中用到的表,看看你是否可以应用WHERE子句进行过滤。一个典型的例子是,当表中只有几千行记录时,一个查询能够很好地执行。但随着应用程序的成长,查询慢了下来。解决方案或许非常简单,限制查询来查看当前月的数据即可。

当你的查询语句带有子查询时,注意在子查询的内部语句上使用过滤,而不是在外部语句上。

只选择你需要的字段

额外的字段通常会增加返回数据的纹理,从而导致更多的数据被返回到SQL客户端。另外:

•使用带有报告和分析功能的应用程序时,有时报告性能低是因为报告工具必须对收到的、带有详细形式的数据做聚合操作。 •偶尔查询也可能运行地足够快,但你的问题可能是一个网络相关的问题,因为大量的详细数据通过网络发送到报告服务器。 •当使用一个面向列的DBMS时,只有你选择的列会从磁盘读取。在你的查询中包含的列越少,IO开销就越小。

移除不必要的表

移除不必要的表的原因,和移除查询语句中不需要的字段的原因一致。

编写SQL语句是一个过程,通常需要大量编写和测试SQL语句的迭代过程。在开发过程中,你可能将表添加到查询中,而这对于SQL代码返回的数据可能不会有任何影响。一旦SQL运行正确,我发现许多人不会回顾他们的脚本,不会删除那些对最终的返回数据没有任何影响和作用的表。通过移除与那些不必要表的JOINS操作,你减少了大量数据库必须执行的流程。有时,就像移除列一样,你会发现你减少的数据又通过数据库返回来了。

移除外部连接查询

这说起来容易做起来难,它取决于改变表的内容有多大的影响。一个解决办法是通过在两个表的行中放置占位符来删除OUTER JOINS操作。假设你有以下的表,它们通过定义OUTER JOINS来确保返回所有的数据:

解决办法是在customer表的行中增加一个占位符,并更新sales表中的所有NULL值到占位符。

你不只是删除了对OUTER JOIN操作的依赖,同时标准化了没有客户的销售人员如何表示。其他开发人员不必编写额外语句,例如ISNULL(customer_id, “No customer yet”)。

删除JOIN和WHERE子句中的计算字段

这是另外一个有时可能说起来容易做起来难的技巧,它取决于你更改表模式的权限大小。可以将连接语句中用到的计算字段作为一个新字段在表中创建。给出以下SQL语句:

在sales表中利用年和月增加一列,可以提高性能。更新后的SQL语句将如下:

总结

上边的建议可以归结为以下几点:

•检查索引 •在所需要的最小数据集上操作 •移除不必要的字段和表 •移除你JOIN和WHERE子句中的计算操作

原文发布于微信公众号 - 马哥Linux运维(magedu-Linux)

原文发表时间:2016-10-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据库

MySQL数据库性能优化之四

优化目标 1.减少 IO 次数 IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 ...

1766
来自专栏无题

悲观锁与乐观锁与事务

事务针对的是行为操作而锁针对的是对象和数据; 事务是指执行行为操作的过程而锁是执行的手段。 悲观锁 悲观锁(Pessimistic Lock), 顾名思义,就...

3197
来自专栏杨建荣的学习笔记

IP地址定位区间的问题分析

以前写过一篇Oracle中关于IP地址定位的问题分析,最后引申出了一系列的问题。当时问题紧急严峻,抓取了10053事件定位源头,想出了一个解决妙法,还自鸣...

2698
来自专栏杨建荣的学习笔记

一个执行计划解析的小问题分析(r9笔记第37天)

前几天,一个开发的同学让我帮忙做一个大查询,给了我一个数据列表,里面的ID有几万个,提供了一个SQL语句,看这情况还得我自己来解析生成相关的SQL了。 假设ID...

2896
来自专栏带你撸出一手好代码

深入浅出数据库索引

前段时间,公司一个新上线的网站出现页面响应速度缓慢的问题, 一位负责这个项目的但并不是搞技术的妹子找到我,让我想办法提升网站的访问速度 ,因为已经有很多用户来投...

3274
来自专栏AhDung

【SQL】分享表值函数FMakeRows,用于生成行

评论中又有一位【笑东风】兄给出改善建议,在此先感谢他。原理是借助行数较多的一个系统视图sys.all_columns与自身做cross join,以得到大量现成...

743
来自专栏CDA数据分析师

十步完全理解 SQL

文 | 水果泡腾片 来源 | 伯乐在线 很多程序员视 SQL 为洪水猛兽。SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言、面向...

2199
来自专栏Java学习网

Java中使用Hibernate系列之加载并存储对象学习(第三节)

经过第一、二节的学习,现在可以使用Hibernate来加载和存储对象了,先编写一个带有main()方法的EventManager类: ? 网络配图 代码如下:...

2177
来自专栏javathings

数据库中的并发控制

任何时候当有多个查询想要操作相同的数据的时候便会产生并发问题,而这很有可能会导致数据库陷入一种不一致的状态。如果恰好出现问题的数据是一批关键数据,那这个后果往往...

702
来自专栏小怪聊职场

MySQL(五)|《千万级大数据查询优化》第二篇:查询性能优化(1)

2558

扫码关注云+社区