可以应用哪些通用技术来优化SQL查询?

时间:2008-09-02 11:59:59

标签: sql performance

可以有效地应用哪些技术来提高SQL查询的性能?是否有适用的一般规则?

11 个答案:

答案 0 :(得分:18)

  • 使用主键
  • 避免选择*
  • 在构建条件语句时尽可能具体。
  • 去标准化通常可以更有效率
  • 表变量和临时表(如果可用)通常比使用大型源表
  • 更好
  • 分区视图
  • 雇用指数和约束

答案 1 :(得分:7)

了解幕后的真实情况 - 您应该能够详细了解以下概念:

  • 索引(不仅仅是它们是什么,而是实际上它们是如何工作的)。
  • 群集索引与堆分配表。
  • 文本和二进制查找以及它们何时可以内联。
  • Fill factor
  • 如何更新/删除记录。
  • 当页面拆分发生时为什么。
  • 统计信息,以及它们如何影响各种查询速度。
  • 查询规划器,以及它如何为您的特定数据库工作(例如在某些系统上“select *”很慢,在规划器可以处理的现代MS-Sql DB上)。

答案 2 :(得分:3)

你可以做的最大的事情是在sql server查询分析器中查找表扫描(确保你打开“show execution plan”)。否则,在MSDN和其他地方有无数的文章会提供很好的建议。

顺便说一句,当我开始学习优化查询时,我针对跟踪运行了sql server query profiler,查看生成的SQL,并试图弄清楚为什么这是一个改进。查询分析器远非最佳,但它是一个不错的开始。

答案 3 :(得分:2)

您可以通过以下几种方法来优化查询效果。

  1. 确保您拥有最少的数据。确保只选择所需的列。将字段大小减小到最小。

  2. 考虑对数据库进行反规范化以减少连接

  3. 避免循环(即获取游标),坚持设置操作。

  4. 将查询实现为存储过程,因为这是预编译的,并且执行速度更快。

  5. 确保您已设置正确的索引。如果您的数据库主要用于搜索,那么请考虑更多索引。

  6. 使用执行计划查看处理是如何完成的。您想要避免的是桌面扫描,因为这样做很昂贵。

  7. 确保将“自动统计”设置为“开启”。 SQL需要这个来帮助决定最佳执行。有关更多信息,请参阅Mike Gunderloy的精彩帖子。 Basics of Statistics in SQL Server 2005

  8. 确保您的索引没有碎片。 Reducing SQL Server Index Fragmentation

  9. 确保您的表格没有碎片。 How to Detect Table Fragmentation in SQL Server 2000 and 2005

答案 4 :(得分:1)

使用 with 语句来处理查询过滤。 将每个子查询限制为可能的最小行数。 然后加入子查询。

WITH
master AS
(
    SELECT SSN, FIRST_NAME, LAST_NAME
    FROM MASTER_SSN
    WHERE STATE = 'PA' AND
          GENDER = 'M'
),
taxReturns AS
(
    SELECT SSN, RETURN_ID, GROSS_PAY
    FROM MASTER_RETURNS
    WHERE YEAR < 2003 AND
          YEAR > 2000
)
SELECT *
FROM master,
     taxReturns
WHERE master.ssn = taxReturns.ssn

with语句中的子查询最终可能与内联视图相同, 或自动生成临时表。我在工作中发现零售数据,大约有70-80%的时间,有一个性能优势。

100%的时间都有维护福利。

答案 5 :(得分:0)

我认为使用SQL查询分析器将是一个良好的开端。

答案 6 :(得分:0)

在Oracle中,您可以查看explain plan来比较查询的变体

答案 7 :(得分:0)

确保您在表格中拥有正确的索引。如果您经常使用列作为订购或限制数据集的方式,那么索引可以产生很大的不同。我在最近的一篇文章中看到,选择distinct可以真正减慢查询速度,特别是如果你没有索引。

答案 8 :(得分:0)

SELECT查询的明显优化是确保在用于连接或WHERE子句的列上有索引。

由于添加索引可能会减慢数据写入速度,因此您需要监控性能以确保不会破坏数据库的写入性能,但这就是使用良好的查询分析工具可以帮助您相应地平衡事物的地方。

答案 9 :(得分:0)

  • 索引
  • 统计
  • on microsoft stack,Database Engine Tuning Advisor

答案 10 :(得分:0)

其他一些要点(我的基于SQL服务器,因为每个数据库后端都有自己的实现,它们可能适用于所有数据库,也可能不适用于所有数据库):

避免在语句的select部分中使用相关子查询,它们本质上是游标。

设计表以使用正确的数据类型,以避免必须对它们应用函数来获取数据。例如,当您将数据存储为varchar时,进行日期数学计算要困难得多。

如果您发现自己经常进行具有功能的连接,那么您需要考虑重新设计表格。

如果您的WHERE或JOIN条件包含OR语句(速度较慢),您可以使用UNION语句获得更好的速度。

UNION ALL比UNION快,如果(并且只有)两个语句是互斥的,并且以任何方式返回相同的结果。

NOT EXISTS通常比NOT IN更快或使用带有ID = null的WHERE子句的左连接

在UPDATE查询中添加WHERE条件以确保不更新已经相等的值。更新10,000,000条记录和4条记录之间的区别非常重要!

如果您要经常查询某些值或使用大型报告,请考虑预先计算某些值。订单中的值总和只需在订单生成或调整时完成,而不是在汇总报表中10,000,000,000个订单的结果时完成。预先计算应该在触发器中完成,以便它们始终是最新的基础数据更改。它也不一定只是数字,我们有一个计算字段,用于连接我们在报告中使用的名称。

警惕标量UDF,它们可能比放置代码要慢。

对于较大的数据集,表格变量的临时表往往更快,对于小数据集则更快。此外,您可以索引临时表。

用户界面中的格式化通常比SQL更快。

请勿返回超出实际需要的数据。

这个看起来很明显,但你不会相信我最终会解决这个问题。不要连接到您不使用的表来过滤记录或实际调用语句的select部分中的某个字段。不必要的连接可能非常昂贵。

创建调用其他视图调用其他视图的视图是一个非常糟糕的主意。当您只需要一次并在基础视图中创建100,000,00条记录以获得最终结果中的6条记录时,您可能会发现您正在连接同一个表6次。

在设计数据库时,请考虑报告的不仅仅是输入数据的用户界面。如果不使用数据则无用,因此请考虑数据在数据库中的使用方式以及如何维护或审核数据。这通常会改变设计。 (这就是为什么让ORM设计你的表是一个糟糕的主意的一个原因,它只考虑数据的一个用例。)影响大多数数据的最复杂的查询是在报告中,因此设计更改以帮助报告可以大大加快查询速度(并简化它们)。

特定于数据库的功能实现可能比使用标准SQL(这是他们销售产品的方式之一)更快,因此请了解您的数据库功能并找出哪些更快。

因为不能经常说,所以正确使用索引,不要太多或太少。并使你的WHERE子句可以sargable(能够使用索引)。