SQL Server:处理XML时OPENXML与SELECT..FROM的比较?

SQL Server:处理XML时OPENXML与SELECT..FROM的比较?,sql,sql-server,xml,sql-server-2005,tsql,Sql,Sql Server,Xml,Sql Server 2005,Tsql,我有以下xml: DECLARE @x XML SET @x = '<data> <add>a</add> <add>b</add> <add>c</add> </data>'; 方法2: 他们都给了我: 问题: 哪种方式更可取 后者比前者或前者有什么优点吗?我更喜欢2。尝试执行计划,第一种方法的成本为97%,而第二种方法的成本仅为3%

我有以下xml:

DECLARE @x XML
SET @x = 
    '<data>
       <add>a</add>
       <add>b</add>
       <add>c</add>
     </data>';
方法2:

他们都给了我:

问题:

哪种方式更可取


后者比前者或前者有什么优点吗?

我更喜欢2。尝试执行计划,第一种方法的成本为97%,而第二种方法的成本仅为3%


一个简单的测试表明,方法1比方法2花费的时间更少。我不会得出任何结论,它总是这样。这取决于XML的结构以及查询XML的方式

要测试的存储过程:

create procedure TestXML
  @X xml
as
set nocount on

select X.N.value('.', 'varchar(8000)')
from @X.nodes('/root/item') as X(N)

go

create procedure TestOpenXML
  @X xml
as
set nocount on

declare @idoc int
exec sp_xml_preparedocument @idoc out, @X

select value
from openxml(@idoc, '/root/item',1) 
  with (value  varchar(8000) '.')

exec sp_xml_removedocument @idoc
测试:

结果方法1:

SQL Server Execution Times:
   CPU time = 63 ms,  elapsed time = 70 ms.
结果方法2:

SQL Server Execution Times:
   CPU time = 156 ms,  elapsed time = 159 ms.

在SQLServer2005上测试

我个人更喜欢方法1——它对我来说更直观,而且不需要sp_xml_PreparedDocument等额外步骤——只是简单易懂use@marc_s除此之外。。。表示1可用于视图等。感谢您的努力:相对于批次,p.s.3%。这批货是什么?其他97%在哪里?在我看来,当涉及到使用XML数据类型时,查询成本估算是不可信的。@RoyiNamir我在一个批次中运行了两个查询。第一个为97%,第二个为3%。如果@PraVn answer与之相反,怎么会花费更少的时间?@RoyiNamir–查询成本与执行时间不一样,而且当涉及XML查询时,查询成本是不可信的。只是一个想法-你将如何解决这个问题?不用费心回答,只要用语言回答。。。谢谢您的时间。@RoyiNamir做了一些测试,使用unpivot看起来比其他答案更有效。我只看过执行计划。没有用大量数据进行测试。@RoyiNamir谢谢。我很高兴能帮上忙。
SET NOCOUNT ON;
DECLARE @BankXml VARCHAR(MAX) = '<ROOT><ITEM BAF="HI" /></ROOT>'
DECLARE @ErrMsg VARCHAR(MAX) ='',@XmlId INT,@TranCount INT
CREATE TABLE #tmptbl(BAF VARCHAR(10))
IF (@BankXml IS NOT NULL)        
    BEGIN        
        EXEC SP_XML_PREPAREDOCUMENT @XmlId OUTPUT, @BankXml
        INSERT INTO #tmptbl(BAF)
        SELECT BAF
        FROM OPENXML(@XmlId, 'ROOT/ITEM', 1) WITH
        (
            BAF VARCHAR(10)
        )                           
    END 
BEGIN TRY
    IF @@TRANCOUNT = 0
        SET @TranCount = 1
    IF @TranCount=1 
        BEGIN TRAN
    IF 1=1
    BEGIN
        SELECT BAF FROM #tmptbl
    END     
    IF @TranCount = 1
        COMMIT TRAN
END TRY
BEGIN CATCH
    IF @@TRANCOUNT = 1 AND @TranCount = 1
    ROLLBACK TRAN
    SET @ErrMsg = 'Error : ' + @ErrMsg + ' : ' + ERROR_MESSAGE()
    RAISERROR(@ErrMsg,16,1)
END CATCH
SQL Server Execution Times:
   CPU time = 63 ms,  elapsed time = 70 ms.
SQL Server Execution Times:
   CPU time = 156 ms,  elapsed time = 159 ms.
SET NOCOUNT ON;
DECLARE @BankXml VARCHAR(MAX) = '<ROOT><ITEM BAF="HI" /></ROOT>'
DECLARE @ErrMsg VARCHAR(MAX) ='',@XmlId INT,@TranCount INT
CREATE TABLE #tmptbl(BAF VARCHAR(10))
IF (@BankXml IS NOT NULL)        
    BEGIN        
        EXEC SP_XML_PREPAREDOCUMENT @XmlId OUTPUT, @BankXml
        INSERT INTO #tmptbl(BAF)
        SELECT BAF
        FROM OPENXML(@XmlId, 'ROOT/ITEM', 1) WITH
        (
            BAF VARCHAR(10)
        )                           
    END 
BEGIN TRY
    IF @@TRANCOUNT = 0
        SET @TranCount = 1
    IF @TranCount=1 
        BEGIN TRAN
    IF 1=1
    BEGIN
        SELECT BAF FROM #tmptbl
    END     
    IF @TranCount = 1
        COMMIT TRAN
END TRY
BEGIN CATCH
    IF @@TRANCOUNT = 1 AND @TranCount = 1
    ROLLBACK TRAN
    SET @ErrMsg = 'Error : ' + @ErrMsg + ' : ' + ERROR_MESSAGE()
    RAISERROR(@ErrMsg,16,1)
END CATCH