【发布时间】:2015-11-19 17:21:47
【问题描述】:
我是一名软件开发人员,最近 DBA 与我接洽,以优化我的应用程序正在使用的查询。 DBA 报告说,查询在运行时会占用大约 50% 的 CPU 和高 I/O 操作。查询非常简单,我不确定如何优化它。
问题 1:如何优化此查询?
问题 2: 这样做是我的工作吗,DBA 不应该更了解这方面的知识吗?请注意,我们没有 DB 开发人员,只有 DBA 和软件开发人员。
DB 有大约 30-5000 万条记录,它由 DBA 不断维护/监控,但我不确定如何。服务器在专用机器上,是Microsoft SQL Server 2005 - 9.00.5057.00 (X64)
PS:请不要提供通过结构更改来改进 DB 的方法,我知道将货币存储为 varchar 是一个糟糕的设计,但就是这样,我们无法更改 DB结构,仅查询访问它。
感谢您提供任何见解。
查询:
SELECT
COALESCE(CAST([PH].[PAmount] AS decimal(15, 2)) + CAST([PH].[Fee] AS decimal(15, 2)), 0.0) AS [PayAmount],
[PH].[PDate] AS [PayDate]
FROM [History] AS [PH] WITH (NOLOCK)
WHERE [PH].[PMode] IN ('C', 'P')
AND [PH].[INNO] = 'XYZ'
AND [PH].[PStatus] IN ('CONSERVED', 'EXPECTING', 'REFRIGERATED', 'POSTPONED', 'FILED')
AND [PH].[Locked] = 1
AND [PH].[PDate] >= 'Jan 1, 2015'
ORDER BY [PH].[PDate] ASC
字段:
PAmount - 非聚集索引,varchar(50)
Fee - 未编入索引,decimal(6,2)
PDate - 聚集索引,datetime
PMode - 非聚集索引,varchar(5)
INNO - 非聚集索引,varchar(50)
PStatus - 非聚集索引,varchar(50)
Locked - 未编入索引,bit
执行计划:
SELECT---Compute Scalar---Filter---NestedLoops-|--Index Seek
(Inner Join) |
cost 0% Cost 0% Cost 0% Cost 0% | cost 4%
|---Key Lookup
Cost 96%
【问题讨论】:
-
表上有什么索引?查询返回多少行?执行计划是什么样的?
-
缺少一些索引,你可以在这里做很多事情。但是,我强烈建议您停止使用 NOLOCK。这是与金钱打交道的,这个提示意味着你的结果不准确。 blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere
-
仅供参考:Sql Server 2005 不到一年就报废了。
-
@Martin:原帖中提供了索引。我已经编辑了执行路径。请让我知道您还需要什么。谢谢。
-
@Sean:强烈建议我们始终使用 NOLOCK。也许它是我们数据库的一个细节——99% 的数据库事务是插入。我们几乎从不进行编辑。如果在重负载表上并行工作,NOLOCK 可防止记录被锁定。
标签: sql sql-server tsql query-optimization