【问题标题】:SQL Server query performance on longer date range较长日期范围内的 SQL Server 查询性能
【发布时间】:2011-11-15 22:18:18
【问题描述】:

我正在尝试查询一个表,该表有一列存储 XML 格式的事务数据。我的文件管理器选项实际上是我的 XML 数据中的节点 1。所以下面是我的查询

SELECT eRefNo, eCreationDate, eData 
FROM TableA
WHERE CAST(CAST(CAST(eData AS text) AS xml ).query('Test/Header/ExportToGMACS/text()')AS nvarchar(1000)) = 'True' 
AND ((CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting1/KindOfPayment[@MPText]')AS nvarchar(1000)) = 'Claims') 
OR (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting1/PaymentDate/text()')AS nvarchar(1000)), 103) >= convert(datetime, '01/01/2011', 103) AND (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting1/PaymentDate/text()')AS nvarchar(1000)), 103) <= convert(datetime, '31/07/2011', 103))) 
OR (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting2/PaymentDate/text()')AS nvarchar(1000)), 103) >= convert(datetime, '01/01/2011', 103) AND (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting2/PaymentDate/text()')AS nvarchar(1000)), 103) <= convert(datetime, '31/07/2011', 103))) 
OR (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting3/PaymentDate/text()')AS nvarchar(1000)), 103) >= convert(datetime, '01/01/2011', 103) AND (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting3/PaymentDate/text()')AS nvarchar(1000)), 103) <= convert(datetime, '31/07/2011', 103))) 
OR (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting4/PaymentDate/text()')AS nvarchar(1000)), 103) >= convert(datetime, '01/01/2011', 103) AND (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting4/PaymentDate/text()')AS nvarchar(1000)), 103) <= convert(datetime, '31/07/2011', 103))) 
OR (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting5/PaymentDate/text()')AS nvarchar(1000)), 103) >= convert(datetime, '01/01/2011', 103) AND (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting5/PaymentDate/text()')AS nvarchar(1000)), 103) <= convert(datetime, '31/07/2011', 103))) 
OR (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting6/PaymentDate/text()')AS nvarchar(1000)), 103) >= convert(datetime, '01/01/2011', 103) AND (CONVERT(datetime, CAST(CAST(CAST(eData AS text) AS xml ).query('Test/PaymentAccountingDetail/PaymentAccounting6/PaymentDate/text()')AS nvarchar(1000)), 103) <= convert(datetime, '31/07/2011', 103)))) 

当我将日期范围设置为从 01/Jan/201131/Jul/2011 进行搜索时,与我的日期范围从 01/Jul/201131/Jul/2011 相比,它需要更快。

我无法理解这个特殊的性能问题。一直以来,我都认为更宽的日期范围将需要更长的时间来执行,因为它有更多的行要返回?

请哪位高手给点意见。

谢谢 约翰逊


我已经尝试过,但无论如何它通过减少单个演员对我的查询没有多大帮助。

我的主要问题是更宽的日期范围过滤器比更短的日期范围过滤器花费更短的时间。

知道是什么原因吗?

我使用的是 MS SQL Server 2005

【问题讨论】:

  • 欢迎来到 StackOverflow!如果您发布代码、XML 或数据示例,在文本编辑器中突出显示这些行,然后单击编辑器工具栏上的“代码示例”按钮 ({ }) 以很好地格式化和语法突出显示它!
  • 知道你可以简化这个 - 对吧? CAST(CAST(CAST(eData AS text) AS xml).query('Test/Header/ExportToGMACS/text()') AS nvarchar(1000)) 可以更容易地写成:CAST(CAST(eData AS text) AS xml).value('(Test/Header/ExportToGMACS)[1]', 'nvarchar(1000)') - 至少可以为您节省一个 CAST
  • 什么 h*** 数据类型是 eData,您必须首先将其转换为 text(我 从不 这样做 - Text 已弃用 -改用varchar(max)!!)然后将其转换为xml......
  • 我已经尝试过,但无论如何它通过减少单个演员表对我的查询没有多大帮助。我的主要暗示问题是更宽的日期范围过滤器比更短的日期范围过滤器花费更短的时间。知道是什么原因吗?我正在使用 MS SQL Server 2005
  • 您可以从此查询中删除所有演员表,但只有一个演员表。添加这样的交叉应用 CROSS APPLY (SELECT CAST(eData AS xml)) as T(X) 然后 T.X.value 以提取您需要的值。像这样的间隔检查T.X.value('(Test/PaymentAccountingDetail/PaymentAccounting1/PaymentDate)[1]', 'datetime') between '20110101' and '20110731'

标签: sql-server sql-server-2005 date-range


【解决方案1】:

此查询未使用索引进行优化,因此必须进行表扫描才能确定应返回哪些行。这意味着将根据 where 子句检查表中的每一行。

您使用castquery 的技术相当昂贵,所以我的猜测(我还没有测试过)是查询优化器缩短了or 条件,这样当你得到一个击中它不会继续检查连续条件。这意味着您可以通过扩展日期范围来节省时间,因为将根据 all or 条件检查更少的行。

【讨论】:

    猜你喜欢
    • 2014-10-28
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多