Sql server SQL查询由于日期函数而运行缓慢
我正在使用ManagementStudio 18对SQLServer数据库运行一个查询,在服务器上运行需要3-4分钟。如果我删除dates函数,它将在1分钟内在我的机器上运行,但我需要dates函数。有人能帮忙吗?提前谢谢你 以下是在服务器上执行3-4的原始查询:Sql server SQL查询由于日期函数而运行缓慢,sql-server,common-table-expression,query-performance,Sql Server,Common Table Expression,Query Performance,我正在使用ManagementStudio 18对SQLServer数据库运行一个查询,在服务器上运行需要3-4分钟。如果我删除dates函数,它将在1分钟内在我的机器上运行,但我需要dates函数。有人能帮忙吗?提前谢谢你 以下是在服务器上执行3-4的原始查询: With A AS ( Select DSS.transactionSynchronizationId, DSS.transactionDate, DSS.transactionTime,
With A AS
(
Select DSS.transactionSynchronizationId, DSS.transactionDate, DSS.transactionTime,
convert (varchar, CAST(DateAdd(minute, DateDiff(minute, 0, DSS.transactionTime), 0) AS smalldatetime), 24) As DSS_TransactionTime_EST, DSS.processedBy,
DSS.transactionType, DSS.country, DSS.state, DSS.partner,
DSS.originUnitPrice, DSS.discount, DSS.taxAmount,
Case When transactionType In ('REFUND', 'CHARGEBACK', 'CREDIT') Then (DSS.taxAmount*-1) Else DSS.taxAmount End As DSS_Tax_Amount,
Case When DSS.country In ('US', 'PR', 'CA') And transactionType In ('REFUND', 'CHARGEBACK', 'CREDIT') Then -DSS.originUnitPrice - DSS.discount
When DSS.country In ('US', 'PR', 'CA') And transactionType Not In ('REFUND', 'CHARGEBACK', 'CREDIT') Then DSS.originUnitPrice - DSS.discount
When DSS.country Not In ('US', 'PR', 'CA') And transactionType In ('REFUND', 'CHARGEBACK', 'CREDIT') Then (-DSS.originUnitPrice - DSS.discount - DSS.taxAmount)
Else DSS.originUnitPrice - DSS.discount - DSS.taxAmount End AS DSS_Gross_Sales
From TableA As DSS
),
C As
(
Select Distinct VTX.[Transaction Synchronization ID], VTX.[Transaction Process Date], VTX.[Transaction Process Time],
convert(varchar, DATEADD (HOUR , -5 , [Transaction Process Time]) , 24) As Vertex_TransactionTime_EST, VTX.[Situs Country Code 2], VTX.[Situs Main Division],
VTX.[Taxpayer Division Code], VTX.[Gross Amount] As VTX_Gross_Amount, Sum (VTX.[Tax Amount]) As VTX_Tax_Amount
From TableB As VTX
Group By VTX.[Transaction Synchronization ID], VTX.[Transaction Process Date], VTX.[Transaction Process Time], VTX.[Situs Country Code 2], VTX.[Situs Main Division],
VTX.[Taxpayer Division Code], VTX.[Gross Amount]
),
B As
(
Select C.[Transaction Synchronization ID], C.[Transaction Process Date], C.[Transaction Process Time],
convert(varchar, DATEADD (HOUR , -5 , C.[Transaction Process Time]) , 24) As Vertex_TransactionTime_EST, C.[Situs Country Code 2], C.[Situs Main Division],
C.[Taxpayer Division Code], Sum (C.VTX_Gross_Amount) As VTX_Gross_Amount, Sum (C.VTX_Tax_Amount) As VTX_Tax_Amount
From C
Group By C.[Transaction Synchronization ID], C.[Transaction Process Date], C.[Transaction Process Time],
convert(varchar, DATEADD (HOUR , -5 , C.[Transaction Process Time]) , 24), C.[Situs Country Code 2], C.[Situs Main Division],
C.[Taxpayer Division Code]
)
Select A.transactionSynchronizationId, B.[Transaction Process Date], B.Vertex_TransactionTime_EST, A.transactionDate, A.DSS_TransactionTime_EST, A.processedBy, A.transactionType,
B.[Situs Country Code 2], A.country, B.[Situs Main Division], A.state, A.partner, B.[Taxpayer Division Code], B.VTX_Gross_Amount, B.VTX_Tax_Amount, A.originUnitPrice,
A.discount, A.DSS_Tax_Amount, A.DSS_Gross_Sales, Cast ((A.DSS_Gross_Sales - B.VTX_Gross_Amount) As decimal (10,2)) As 'Gross Sales Diff',
A.DSS_Tax_Amount, Cast (A.DSS_Tax_Amount - B.VTX_Tax_Amount As decimal (10,2)) As 'Tax Diff'
From A Join B
On A.transactionSynchronizationId = B.[Transaction Synchronization ID]
以下是运行速度更快的查询:
With A AS
(
Select DSS.transactionSynchronizationId, DSS.transactionDate, DSS.transactionTime,
convert (varchar, CAST(DateAdd(minute, DateDiff(minute, 0, DSS.transactionTime), 0) AS smalldatetime), 24) As DSS_TransactionTime_EST, DSS.processedBy,
DSS.transactionType, DSS.country, DSS.state, DSS.partner,
DSS.originUnitPrice, DSS.discount, DSS.taxAmount,
Case When transactionType In ('REFUND', 'CHARGEBACK', 'CREDIT') Then (DSS.taxAmount*-1) Else DSS.taxAmount End As DSS_Tax_Amount,
Case When DSS.country In ('US', 'PR', 'CA') And transactionType In ('REFUND', 'CHARGEBACK', 'CREDIT') Then -DSS.originUnitPrice - DSS.discount
When DSS.country In ('US', 'PR', 'CA') And transactionType Not In ('REFUND', 'CHARGEBACK', 'CREDIT') Then DSS.originUnitPrice - DSS.discount
When DSS.country Not In ('US', 'PR', 'CA') And transactionType In ('REFUND', 'CHARGEBACK', 'CREDIT') Then (-DSS.originUnitPrice - DSS.discount - DSS.taxAmount)
Else DSS.originUnitPrice - DSS.discount - DSS.taxAmount End AS DSS_Gross_Sales
From TableA As DSS
),
C As
(
Select Distinct VTX.[Transaction Synchronization ID], VTX.[Transaction Process Date], VTX.[Transaction Process Time],
convert(varchar, DATEADD (HOUR , -5 , [Transaction Process Time]) , 24) As Vertex_TransactionTime_EST, VTX.[Situs Country Code 2], VTX.[Situs Main Division],
VTX.[Taxpayer Division Code], VTX.[Gross Amount] As VTX_Gross_Amount, Sum (VTX.[Tax Amount]) As VTX_Tax_Amount
From TableB As VTX
Group By VTX.[Transaction Synchronization ID], VTX.[Transaction Process Date], VTX.[Transaction Process Time], VTX.[Situs Country Code 2], VTX.[Situs Main Division],
VTX.[Taxpayer Division Code], VTX.[Gross Amount]
),
B As
(
Select C.[Transaction Synchronization ID], C.[Transaction Process Date], C.[Transaction Process Time],
C.[Situs Country Code 2], C.[Situs Main Division],
C.[Taxpayer Division Code], Sum (C.VTX_Gross_Amount) As VTX_Gross_Amount, Sum (C.VTX_Tax_Amount) As VTX_Tax_Amount
From C
Group By C.[Transaction Synchronization ID], C.[Transaction Process Date], C.[Transaction Process Time],
C.[Situs Country Code 2], C.[Situs Main Division],
C.[Taxpayer Division Code]
)
Select A.transactionSynchronizationId, B.[Transaction Process Date], A.transactionDate, A.DSS_TransactionTime_EST, A.processedBy, A.transactionType,
B.[Situs Country Code 2], A.country, B.[Situs Main Division], A.state, A.partner, B.[Taxpayer Division Code], B.VTX_Gross_Amount, B.VTX_Tax_Amount, A.originUnitPrice,
A.discount, A.DSS_Tax_Amount, A.DSS_Gross_Sales,
A.DSS_Tax_Amount, Cast (A.DSS_Tax_Amount - B.VTX_Tax_Amount As decimal (10,2)) As 'Tax Diff'
From A Join B
On A.transactionSynchronizationId = B.[Transaction Synchronization ID]
应采取的措施:
- 简化你的疑问,肯定有办法吗?似乎存在聚合冗余
- 运行执行计划,找出瓶颈所在
- 尝试分别运行每个块,您可能会发现其中一个块比其他块花费的时间要多得多
- 显示表结构,包括索引和一些示例数据,查询优化器可能无法利用该查询的索引
- 改进命名约定:表名别名(如A、B、C)没有意义,它们代表什么还不清楚,混淆的风险更高
- 如果查询是存储过程的一部分:
- 有时您可以使用变量而不是复杂的表达式(对于只需要计算一次的值)
- 使用临时表,并分多个步骤填充它们-尝试生成单个CTE可能会导致性能降低
- 也许你也可以用
子句过滤出源表,在不知道数据和目的的情况下很难判断,但我的印象是你正在提取所有数据,然后对其进行聚合WHERE
convert(varchar, DATEADD (HOUR , -5 , C.[Transaction Process Time]) , 24) As Vertex_TransactionTime_EST,
如果您真的必须这样做,也许可以尝试不同的形式,摆脱varchar转换。您只返回带有时区偏移的HH:mm:ss
说到这里,我想我应该提到SQL Server有时区函数,例如,或者-很高兴知道它们的存在。这些查询非常难以阅读。也许可以尝试删除与问题无关的部分,并为我们提供一个更简单的查询。但是,如果您不需要CTE中的日期函数作为join/where子句,请将它们拉到返回实际数据的select语句中。它正在运行哪个版本的SQL Server?您希望从
B
中得到哪些不需要从C
中得到的内容B
聚合C
的列,添加一个额外的列,该列的日期计算将[Transaction Process Time]
获取到最接近的秒数,但行仍然由[Transaction Process Time]
聚合,因此总和将仍然相同。。。