可以有效地应用哪些技术来提高SQL查询的性能?是否有适用的一般规则?
答案 0 :(得分:18)
答案 1 :(得分:7)
了解幕后的真实情况 - 您应该能够详细了解以下概念:
答案 2 :(得分:3)
你可以做的最大的事情是在sql server查询分析器中查找表扫描(确保你打开“show execution plan”)。否则,在MSDN和其他地方有无数的文章会提供很好的建议。
顺便说一句,当我开始学习优化查询时,我针对跟踪运行了sql server query profiler,查看生成的SQL,并试图弄清楚为什么这是一个改进。查询分析器远非最佳,但它是一个不错的开始。
答案 3 :(得分:2)
您可以通过以下几种方法来优化查询效果。
确保您拥有最少的数据。确保只选择所需的列。将字段大小减小到最小。
考虑对数据库进行反规范化以减少连接
避免循环(即获取游标),坚持设置操作。
将查询实现为存储过程,因为这是预编译的,并且执行速度更快。
确保您已设置正确的索引。如果您的数据库主要用于搜索,那么请考虑更多索引。
使用执行计划查看处理是如何完成的。您想要避免的是桌面扫描,因为这样做很昂贵。
确保将“自动统计”设置为“开启”。 SQL需要这个来帮助决定最佳执行。有关更多信息,请参阅Mike Gunderloy的精彩帖子。 Basics of Statistics in SQL Server 2005
确保您的索引没有碎片。 Reducing SQL Server Index Fragmentation
答案 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)
答案 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(能够使用索引)。