SQL 性能:初学者最佳实践





3.00/5 (16投票s)
本文提供了一些简单实用的指南,帮助开发人员设计高性能、高质量的 SQL 数据库。
引言
大多数开发人员都是“偶然的开发者”,直到客户报告问题才发现数据库性能问题。如果您重视这些指南,就可以将性能标准化到一个稳定的水平。我写这篇文章是基于我自己的经验和知识。由于互联网是一个广阔的资源,就像大多数专业人士一样,我从浏览时阅读的文章中也获得了这类信息。
本文提供的语句可能不适用于所有数据库,因为并非所有数据库系统都具备所有功能(例如:存储过程)。
SQL 性能:初学者最佳实践
- 将大表分割成多个小表。(在 SQL 术语中,我们称之为规范化。)
- 使用查找表。这有助于减少表的负担。例如:如果您有一个产品销售表,并且想存储同一产品的 3 张图片,与其在表中添加三个列,不如使用一个查找表。这样,您就可以自由添加任意数量的照片。
- 另外,只使用必需的列。例如:如果您有 A 和 B 列,并且在另一列 C 中有它们的总和。您根本不需要 C 列,因为我们可以通过语句重现相同的表效果。
SELECT A, B, (A+B) AS C FROM TABLE1
如果主键是数字型或数据宽度较小,则数据库性能会提高。
- 不要使用数据库存储图像。一种好的方法是只在表中存储 URL,而将图像文件存储在磁盘上。
- 但是,如果您有一个大型数据库、大量计算和频繁调用,并且输出表的结果几乎是静态的(例如:员工多年的薪资明细数据),那么规范化有时可能会失败。在这种情况下,您可以通过使用反规范化表来提高性能。但这也有很多缺点,比如数据库非常大等等。
- 定义列时使用正确的数据类型和宽度。例如:如果您想存储“
年龄
”,则不需要使用VARCHAR
字段,因为TINYINT
就可以完成工作。(TINYINT
可以存储 0 到 255 之间的整数数据。您知道没有人的年龄会超过 255。) - 开始行动吧!如果您还没有使用主键、外键等的习惯。
- 使用存储过程和函数,而不是将所有混乱的代码都写在程序本身中。这不仅能提高性能,而且在安全方面也很有优势。
- 始终尝试保留一个错误表来记录来自存储过程或函数的所有错误。在 T-SQL(版本 < 2000)中,您可以使用全局变量
@@ERROR
来检测错误。从 2005 或更高版本开始,您可以使用TRY
/CATCH
,这在当今的高级语言中是可用的。它有助于您节省时间,避免因查找“bug 在哪里?”而产生的烦恼。 - 使用事务来避免在执行存储过程期间数据丢失。失败的可能性很高。可能是数据截断问题、网络问题等。在 MSSQL 中,我们有
BEGIN TRANSACTION
、COMMIT TRANSACTION
和ROLLBACK TRANSACTION
可用。请将它们与错误处理方法结合使用。关于性能,与普通语句相比,事务的性能会下降一步,但考虑到产品的质量,它非常高。 - 避免使用 CURSOR。只有在别无选择时才使用。在大多数情况下,CURSOR 会消耗大量时间,因为它是一个逐条记录处理的过程。
- 避免使用 GOTO。这不仅针对 SQL,也适用于所有编程语言。GOTO 语句被认为是非结构化的,并且有可能超出我们的控制范围。但也有一些情况是我们无法避免 GOTO 的。
- 避免使用
IF
并开始使用CASE
。 - 编写可读性强的代码。
- 使用正确的缩进。
- 将所有语句大写。
- 数据类型使用小写。
- 对所有用户创建的对象使用大驼峰命名法(也称为 Pascal 命名法)。例如:
@EmployeeCode
。 - 使用有意义的用户定义标识符。只使用包含 A-Z、a-Z、0-9 和下划线字符的名称。不要使用区域性特殊字符。
- 在存储过程名称中也指定执行的操作。例如:
spEmployeeUpdate
。 - 调用 SQL 对象时始终使用模式。例如:
EXEC dbo.spEmployeeUpdat
。 - 使用
BEGIN
和END
来指定语句块。 - 在需要对多个表进行操作时使用别名。
- 尽管 AS 关键字是可选的,但请始终使用。
- 使用适当的注释。并在所有过程、函数等的顶部添加目的、作者、日期、版本等详细信息。
- 在存储过程内添加包含语句的测试数据并注释掉。这有助于您将来进行调试。同时,这也有助于其他开发人员快速上手。
- 进行正确的索引。在非常大的表上应用
INDEX
时会有明显的区别。 - 在
SELECT
、INSERT
、UPDATE
语句中始终使用列名。避免使用星号(*)。 - 避免在存储过程内使用动态 SQL 语句,即不要使用 SQL 语句来创建 SQL 语句。
- 在带有
LIKE
子句的SELECT
字符串时要小心。如果使用不当,可能会导致性能问题。
历史
- 2007 年 5 月 18 日 版本 1.0
- 2007 年 5 月 23 日 版本 1.1