Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server XML列性能_Sql Server_Xml_Performance_Tsql_Xquery - Fatal编程技术网

Sql server SQL Server XML列性能

Sql server SQL Server XML列性能,sql-server,xml,performance,tsql,xquery,Sql Server,Xml,Performance,Tsql,Xquery,将包含XML的nText列转换为XML数据类型会导致SQL Server中的性能下降 我目前正在从事一个项目,其中使用了nText列来存储有效的XML。我已经成功地将这些列迁移到XML数据类型。然而,根据SQLProfiler,XML数据类型的性能比使用nText或nvarchar(max)存储XML要差。我所读到的一切都暗示,情况不应该如此 为了验证这一点,我创建了两个具有相同索引的表等 Table Name Order1 [id] [int] IDENTITY(1,1) NOT NULL,

将包含XML的nText列转换为XML数据类型会导致SQL Server中的性能下降

我目前正在从事一个项目,其中使用了nText列来存储有效的XML。我已经成功地将这些列迁移到XML数据类型。然而,根据SQLProfiler,XML数据类型的性能比使用nText或nvarchar(max)存储XML要差。我所读到的一切都暗示,情况不应该如此

为了验证这一点,我创建了两个具有相同索引的表等

Table Name Order1
[id] [int] IDENTITY(1,1) NOT NULL,
[uid] [varchar](36) NOT NULL,
[AffiliateId] [varchar](36) NOT NULL,
[Address] [ntext] NOT NULL,
[CustomProperties] [ntext] NOT NULL,
[OrderNumber] [nvarchar](50) NOT NULL,
...

Table Name Order2
[id] [int] IDENTITY(1,1) NOT NULL,
[uid] [varchar](36) NOT NULL,
[AffiliateId] [varchar](36) NOT NULL,
[Address] [xml] NOT NULL,
[CustomProperties] [xml] NOT NULL,
[OrderNumber] [nvarchar](50) NOT NULL,
...
然后,我使用select/insert语句复制了数据,并在两个表上重建了索引。然后,我使用以下SQL创建了一个脚本

DBCC DROPCLEANBUFFERS
GO
--Part1
Select id, uid, AffiliateId, Address, CustomProperties, OrderNumber from [dbo].[Order1] where uid = 'F96045F8-A2BD-4C02-BECB-6EF22C9E473F'
Select id, uid, AffiliateId, Address, CustomProperties, OrderNumber from [dbo].[Order1] where uid = 'A3B71348-EB68-4600-9550-EC2CF75698F4'
Select id, uid, AffiliateId, Address, CustomProperties, OrderNumber from [dbo].[Order1] where uid = 'CB114D91-F000-4553-8AFE-FC20CF6AD8C0'
Select id, uid, AffiliateId, Address, CustomProperties, OrderNumber from [dbo].[Order1] where uid = '06274E4F-E233-4594-B505-D4BAA3770F0A'

DBCC DROPCLEANBUFFERS
GO
--Part2
Select id, uid, AffiliateId, Address, OrderNumber,  
CAST(CustomProperties AS xml).query('CustomProperty/Key[text()="AgreedToTerms"]/../Value/text()')  as "TermsAgreed" 
from Order1

DBCC DROPCLEANBUFFERS
GO
--Part3
Insert Into Order1 uid, AffiliateId, Address, CustomProperties, OrderNumber
Select NewId(), AffiliateId, Address, CustomProperties, OrderNumber + 'X' from [dbo].[Order1] where uid = 'F96045F8-A2BD-4C02-BECB-6EF22C9E473F'

Insert Into Order1 uid, AffiliateId, Address, CustomProperties, OrderNumber
Select NewId(), AffiliateId, Address, CustomProperties, OrderNumber + 'X' from [dbo].[Order1] where uid = 'A3B71348-EB68-4600-9550-EC2CF75698F4'

Insert Into Order1 uid, AffiliateId, Address, CustomProperties, OrderNumber
Select NewId(), AffiliateId, Address, CustomProperties, OrderNumber + 'X' from [dbo].[Order1] where  uid = 'CB114D91-F000-4553-8AFE-FC20CF6AD8C0'

Insert Into Order1 uid, AffiliateId, Address, CustomProperties, OrderNumber
Select NewId(), AffiliateId, Address, CustomProperties, OrderNumber + 'X' from [dbo].[Order1] where uid = '06274E4F-E233-4594-B505-D4BAA3770F0A'

DBCC DROPCLEANBUFFERS
GO
-- Part4 This updates a .5M row table.
Update [dbo].[Order1] Set CustomProperties = Cast(CustomProperties as NVARCHAR(MAX)) + CAST('' as NVARCHAR(MAX)), Address = Cast(CustomProperties as NVARCHAR(MAX)) + CAST('' as NVARCHAR(MAX))
SQL事件探查器的平均结果如下所示:-

NTEXT

+-------+-------------+-------------+-------------+-------------+
| Test  |     CPU     |    Reads    |   Writes    |  Duration   |
+-------+-------------+-------------+-------------+-------------+
| Part1 | 281.3333333 | 129.3333333 |           0 |         933 |
| Part2 | 78421.66667 |     5374306 | 10.66666667 | 47493.66667 |
| Part3 | 281.6666667 |         616 | 27.66666667 | 374.6666667 |
| Part4 | 40312.33333 | 15311252.67 |      320662 |       67010 |
| Total |             |             |             | 115811.3333 |
+-------+-------------+-------------+-------------+-------------+


XML

+-------+-------------+-------------+-------------+-------------+
| Test  |     CPU     |    Reads    |   Writes    |  Duration   |
+-------+-------------+-------------+-------------+-------------+
| Part1 |         282 | 58.33333333 |           0 | 949.3333333 |
| Part2 | 21129.66667 | 180143.3333 |           0 | 76048.66667 |
| Part3 |         297 | 370.3333333 | 14.66666667 |         378 |
| Part4 | 112578.3333 | 8908940.667 | 145703.6667 | 114684.3333 |
| Total |             |             |             | 192060.3333 |
+-------+-------------+-------------+-------------+-------------+
测试脚本有缺陷吗?或者,是否需要对xml数据类型列进行其他优化


我希望XML列类型的性能优于ntext。

所以这可能不是一个答案,至少不是一个解决方案,但希望它能帮助理解正在发生的事情

XML最昂贵的部分是初始解析,换句话说:文本表示和技术存储之间的转换

重要的是要知道:原生XML不是作为您看到的文本存储的,而是作为层次表存储的。当您将一些文本XML传递到SQL Server时,这需要非常繁重的处理。为人类读者调用此XML需要相反的过程。将此字符串存储在字符串列中(请注意,
NTEXT
几个世纪以来一直被弃用)比将其存储为原生XML要快,但会失去许多优势

因此,对于您的脚本:

我假设您运行了相同的脚本,但只是将
Order1
更改为
Order2
。这是正确的吗

第1部分测量一个简单的
SELECT
。 为了提供可读的表示,SQLServer(或者更确切地说是SSMS)将把任何值转换为某种文本。如果您的表包含int、guid或DateTime,您将看不到实际的位模式,是吗?SSM将使用非常昂贵的操作为您创建可读的内容。代价高昂的部分是转型。字符串不需要这个,所以NTEXT会更快

第2部分度量了
.query()
方法(还涉及“如何显示结果”)。 您是否也将
CAST(作为XML)
Order2
一起使用?然而,有了这样的需求,XML应该会更快,因为NTEXT将不得不反复进行繁重的解析,而XML已经以可查询的格式存储。。。但是您的XQuery是次优的(由于向后导航
。/Value
)。试试这个:

 .query('/CustomProperty[Key[text()="AgreedToTerms"]]/Value/text()')
这将查找具有给定内容的
,并将阅读
下面的
,而无需
。/

我当然希望XML在这里的转换比NTEXT更好。。。对全新表和索引的第一次调用可能会返回有偏差的结果

第3部分措施插入 在这里,我希望能有同样的表现。。。如果您将一个字符串值移动到另一个字符串列中,这就是简单的复制。将本机XML移动到另一个XML列也很简单

第4部分措施更新 这看起来很奇怪。。。你想达到什么目标?代码需要将本机XML转换为字符串,并重新解析它们以存储在XML中。对NTEXT执行同样的操作根本不需要这些昂贵的操作

一些普遍的想法
  • 如果您从外部获取一些XML,从文件中读取它,并且只需要查询一次,那么字符串类型上的字符串方法可以更快,但是:如果您想永久存储XML以便更频繁地使用和操作它们的值,则本机XML类型会更好
  • 在许多情况下,绩效指标并不能衡量你认为你做了什么
  • 尝试以一种方式创建测试,即结果的表示不属于测试的一部分(例如,对临时表执行
    插入
    ,停止时钟并按下临时表的输出)
  • 更新“第2部分”的另一个测试 尝试以下测试脚本:

    使用master;
    去
    创建数据库testShnugo;
    去
    使用testShnugo;
    去
    创建表dbo.with字符串(ID INT,SomeXML NTEXT);
    创建表dbo.WithXML(ID INT,SomeXML);
    去
    --在两个表中插入100.000行
    将计数(Nmbr)设置为(从主控..spt_值v1交叉连接主控..spt_值v2)中选择(ORDER BY(SELECT NULL))上方的前100000行编号()
    插入dbo.WithXML(ID,SomeXML)
    选择Nmbr,(选择Nmbr作为[@Nmbr],选择CONCAT('hallo',Nmbr)作为[SomeTest/@FindMe],选择CONCAT('SomeTestValue',Nmbr)作为[SomeTest],用于XML路径('row')、根('ROOT')、类型)
    从理货
    --将所有内容复制到第二个表中
    使用字符串(ID,SomeXML)从dbo.WithXML中选择ID,CAST(SomeXML作为NVARCHAR(MAX));
    去
    --检查实际内容
    从dbo.WithString中选择*;
    从dbo.WithXML中选择*;
    去
    声明@d DATETIME2=SYSUTCDATETIME();
    从dbo.with字符串中选择*,其中包含一些XML,如“%FindMe=”hallo333“%”
    打印“类似字符串方法”
    打印日期差(毫秒,@d,SYSUTCDATETIME());
    设置@d=SYSUTCDATETIME();
    选择*FROM dbo.WithString WHERE CAST(SomeXML作为xml)。exist('/root/row[SomeTest[@FindMe=“hallo333”]')=1
    打印“将NTEXT转换为XML和.exist()”
    打印日期差(毫秒,@d,SYSUTCDATETIME());
    设置@d=SYSUTCDATETIME();
    选择*FROM dbo.WithXML WHERE CAST(SomeXML作为nvarchar(MAX)),如“%FindMe=”hallo333“%”
    打印“将XML转换为NVARCHAR(MAX)后的字符串方法”
    打印日期差(毫秒,@d,SYSUTCDATETIME());
    设置@d=SYSUTCDATETIME();
    选择*FROM dbo.WithXML,其中SomeXML.exist('/root/row[SomeTest[@FindMe=“hallo333”]]')=1
    打印“带.exist()的本机XML”
    打印日期差(毫秒,@d,SYSUTCDATETIME());
    去
    使用master;
    去
    删除数据库testShnugo;
    
    <root>
      <row nmbr="1">
        <SomeTest FindMe="hallo1">SomeTestValue1</SomeTest>
      </row>
    </root>
    
    String-Method LIKE 
    836
    
    CAST NTEXT to XML and .exist()
    1962
    
    String-Method LIKE after CAST XML to NVARCHAR(MAX)
    1079
    
    native XML with .exist()
    911
    
        SELECT Nmbr,(SELECT TOP 100 Nmbr AS [@nmbr],CONCAT('hallo',x.Nmbr) AS [SomeTest/@FindMe],CONCAT('SomeTestValue',x.Nmbr) As [SomeTest] FROM Tally x FOR XML PATH('row'),ROOT('root'),TYPE)
    
    <root>
      <row nmbr="1">
        <SomeTest FindMe="hallo1">SomeTestValue1</SomeTest>
      </row>
      <row nmbr="2">
        <SomeTest FindMe="hallo2">SomeTestValue2</SomeTest>
      </row>
      <row nmbr="3">
        <SomeTest FindMe="hallo3">SomeTestValue3</SomeTest>
      </row>
      ...more of them
    
    String-Method LIKE 
    71959
    
    CAST NTEXT to XML and .exist()
    74773
    
    String-Method LIKE after CAST XML to NVARCHAR(MAX)
    104380
    
    native XML with .exist()
    16374