【发布时间】: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/2011 到 31/Jul/2011 进行搜索时,与我的日期范围从 01/Jul/2011 到 31/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