IT *_*her 1 performance xml sql-server-2008-r2 xquery query-performance
我使用下面的查询来搜索整个 xml 中的子字符串(包括节点名称和节点值)
SELECT *
FROM tablename
WHERE ( Charindex('abc',CAST([xmlcolumn] AS VARCHAR(MAX)))>0 )
Run Code Online (Sandbox Code Playgroud)
我想要一个性能比这更好的替代查询。所以请推荐一些。详情如下: 表:
CREATE TABLE [dbo].[tablename](
[Sl_no] [int] NOT NULL,
[Date] [date] NULL,
[Operation] [nvarchar](max) NULL,
[Allot] [nvarchar](50) NULL,
**[xmlcolumn]** [xml] NULL,
[By] [nvarchar](255) NULL,
[Dept] [nvarchar](255) NULL,
[Db] [varchar](255) NULL,
[tabl] [varchar](255) NULL,
[Remark] [varchar](5000) NULL,
[Work] [int] NULL,
[F2] [nvarchar](max) NULL,
[F6] [nvarchar](max) NULL,
[F5] [nvarchar](max) NULL,
[F8] [nvarchar](max) NULL,
[ListC] [nvarchar](255) NULL,
[pro] [nvarchar](max) NULL,
[Completed] [varchar](50) NULL,
[WorkTime] [xml] NULL,
[RelatedData] [varchar](255) NULL,
[User] [xml] NULL,
[TeBy] [xml] NULL,
[Date1] [nvarchar](50) NULL,
[Num1] [nvarchar](50) NULL,
CONSTRAINT [PK_DBChanges] PRIMARY KEY CLUSTERED
(
[Sl_no] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
行数:3000 列中的示例 xml:(节点数可能会略有变化。
<Root>
<Row>
<User>abs</User>
<Rowid>1</Rowid>
</Row>
<Row>
<User>xra</User>
<Rowid>2</Rowid>
</Row>
<Maxrowid>2</Maxrowid>
</Root>
Run Code Online (Sandbox Code Playgroud)
预期搜索类型:在 xml 列“xmlcolumn”中搜索子字符串,然后返回包含该子字符串的完整行。
所以我使用的查询是
SELECT *
FROM tablename
WHERE ( Charindex('abc',CAST([xmlcolumn] AS VARCHAR(MAX)))>0 )
Run Code Online (Sandbox Code Playgroud)
使用设置统计时间进行查询的IO
SQL Server Execution Times:
CPU time = 62 ms, elapsed time = 93 ms.
Run Code Online (Sandbox Code Playgroud)
我尝试了另一个查询(但它只会在节点值中搜索)
select *
from tablename
where xmlcolumn.exist('//*/text()[contains(., "abc")]') = 1
Run Code Online (Sandbox Code Playgroud)
统计输出为
SQL Server Execution Times:
CPU time = 63 ms, elapsed time = 109 ms.
Run Code Online (Sandbox Code Playgroud)
要知道您将获得什么性能,您必须对数据进行测试。我显然不能这样做,所以我编写了自己的 xml 数据来测试您在这个问题中的两个查询。
创建一个包含 5000 行的表,其中包含 415 个节点、9475 个字符的 XML 文档:
create table T
(
ID int identity primary key,
XMLCol xml not null
)
declare @X xml =
(
select top 100 *
from master..spt_values
for xml path('row'), root('root'), type
)
insert into T(XMLCol)
select top(5000) @X
from master..spt_values as m1, master..spt_values as m2
Run Code Online (Sandbox Code Playgroud)
执行查询以搜索第一个节点 ( ) 中存在的值rpc
和最后一个节点 ( ) 中存在的另一个值SERVER ROLE
。
select count(*)
from T
where charindex('rpc',cast(xmlcol as varchar(max))) > 0
select count(*)
from T
where XMLCol.exist('//*/text()[contains(., "rpc")]') = 1
select count(*)
from T
where charindex('SERVER ROLE',cast(xmlcol as varchar(max))) > 0
select count(*)
from T
where XMLCol.exist('//*/text()[contains(., "SERVER ROLE")]') = 1
Run Code Online (Sandbox Code Playgroud)
不同查询的 IO 是相同的,因此这里是使用的输出set statistics time on
rpc
使用 charindex搜索:
SQL Server Execution Times:
CPU time = 1435 ms, elapsed time = 1434 ms.
Run Code Online (Sandbox Code Playgroud)
搜索rpc
xml 存在
SQL Server Execution Times:
CPU time = 63 ms, elapsed time = 68 ms.
Run Code Online (Sandbox Code Playgroud)
SERVER ROLE
使用 charindex搜索
SQL Server Execution Times:
CPU time = 7316 ms, elapsed time = 7321 ms.
Run Code Online (Sandbox Code Playgroud)
搜索SERVER ROLE
xml 存在
SQL Server Execution Times:
CPU time = 3245 ms, elapsed time = 3244 ms.
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,XML 查询都是明显的赢家。它可以更好地扫描整个 XML,并且可以更好地在找到搜索字符串时提前终止。
对于上面使用 SQL Server 2012 的测试数据来说确实如此。您的数据和搜索字符串可能会有所不同。您必须进行测试才能知道什么最适合您。
注意:正如您的其他问题的答案中所述,上面的两个查询不会返回相同的结果,因为 XML 查询仅搜索节点值,而 charindex 查询搜索整个 XML 文档,包括节点名和标记。
归档时间: |
|
查看次数: |
46087 次 |
最近记录: |