2011-09-13 41 views
3

我想查询一个表,它有一列存储XML中的事务数据。我的文件选项实际上是我的XML数据中的节点的一个。所以,下面是我的查询在更长的日期范围内的SQL Server查询性能

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/201131/Jul/2011需要更快。

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

任何专家在那里请指教。

感谢 约翰逊


我都试过,反正它不利于我的查询多通过减少一个演员。

我的主要impt问题是更短的日期范围筛选器比较短的日期范围筛选器花费的时间更短。

有什么想法是什么原因呢?

我使用MS SQL Server 2005的

+1

欢迎来到StackOverflow!如果您发布代码,XML或数据样本,请**在文本编辑器中突出显示这些行,然后单击编辑器工具栏上的“代码示例”按钮(“{}”),以精确地格式化和语法突出显示它! –

+0

你**知道**你可以简化这个 - 对吗? 'CAST(CAST(CAST(eData AS text)AS xml).query('Test/Header/ExportToGMACS/text()')AS nvarchar(1000))''可以更容易地写成:'CAST(CAST(eData AS文本)AS xml).value('(Test/Header/ExportToGMACS)[1]','nvarchar(1000)')' - 至少可以节省一个CAST –

+0

什么h ***数据类型是'eData'首先将其转换为'text'(我不会**做 - 不推荐使用'Text' - 使用'varchar(max)'代替!!),然后将其转换为'xml' ..... –

回答

0

这查询不使用索引优化,从而必须有一个表扫描找出应返回哪些行。这意味着表格中的每一行都将根据where子句进行检查。

您与castquery技术是相当昂贵的,所以我猜测(我没有测试过这一点)是查询优化器快捷方式or条件,所以,当你得到一击将不再继续检查连续的条件。这意味着您可以通过扩大日期范围来节省时间,因为将根据全部or条件检查更少的行。