SELECT CAST (
REPLACE (
REPLACE (
XEventData.XEvent.value ('(data/value)[1]', 'varchar(max)'),
'<victim-list>', '<deadlock><victim-list>'),
'<process-list>', '</victim-list><process-list>')
AS XML) AS DeadlockGraph
FROM (SELECT CAST (target_data AS XML) AS TargetData
FROM sys.dm_xe_session_targets st
JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address
WHERE [name] = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
WHERE XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report';
Run Code Online (Sandbox Code Playgroud)
在我的机器上完成大约需要 20 分钟。报告的统计数据是
Table 'Worktable'. Scan count 0, logical reads 68121, physical reads 0, read-ahead reads 0,
lob logical reads 25674576, lob …Run Code Online (Sandbox Code Playgroud) xml sql-server execution-plan database-internals sql-server-2012
为了在那里给出答案,我做了以下测试场景。
首先我创建一个测试表并用 100.000 行填充它。一个随机数(0 到 1000)应该为每个随机数产生 ~100 行。这个数字被放入一个 varchar col 并作为一个值放入您的 XML。
然后我做一个像 OP 那样的调用,需要它使用 .exist() 和 .nodes() ,第二个有一个小优势,但都需要 5 到 6 秒。事实上,我调用了两次:第二次以交换的顺序和稍微改变的搜索参数和“//item”而不是完整路径来避免通过缓存结果或计划产生误报。
现在 - 真正让我感到惊讶的是什么!-在.nodes用完整路径是比以前(9秒)慢得多,但.exist()下降到半秒,用全路径甚至下降到约0.10秒。(同时.nodes()具有短的路径比较好,但仍远远落后于.exist())
我自己的测试简而言之:XML 索引可以极大地破坏数据库。它们可以极大地加快速度(s.edit 2),但也可以减慢您的查询速度。我想了解它们是如何工作的...什么时候应该创建一个 XML 索引?为什么.nodes()有索引比没有索引更糟糕?如何避免负面影响?
CREATE TABLE #testTbl(ID INT IDENTITY PRIMARY KEY, SomeData VARCHAR(100),XmlColumn XML);
GO
DECLARE @RndNumber VARCHAR(100)=(SELECT CAST(CAST(RAND()*1000 AS INT) AS VARCHAR(100)));
INSERT INTO #testTbl VALUES('Data_' + …Run Code Online (Sandbox Code Playgroud) 我有一个很大的查询(如有必要,我会在此处发布)并且出现此错误:
消息 6841,级别 16,状态 1,第 1 行
FOR XML 无法序列化节点“NoName”的数据,因为它包含 XML 中不允许的字符 (0x0000)。要使用 FOR XML 检索此数据,请将其转换为 binary、varbinary 或 image 数据类型并使用 BINARY BASE64 指令。
我唯一使用的部分FOR XML在这里:
WHERE
(CodFuncionario = Results.CodFuncionario)
FOR XML PATH(''), TYPE).value('(./text())[1]',
'VARCHAR(MAX)'), 1, 2, '') AS [Experiencia]
Run Code Online (Sandbox Code Playgroud)
但是,什么是node noname?以及如何查找此值:(0x0000)
这是子查询之一(我拥有 FOR XML 的唯一部分):
SELECT
[CodFuncionario],
STUFF
(
(
SELECT
' / ' +
CAST
(
[DescFuncao] + '-' +
[DescTempoExperiencia]
AS VARCHAR(MAX)
)...
FROM
[Linked_Server].db.dbo.tblFuncionarioExperiencia T0
INNER JOIN
[Linked_Server].db.dbo.tblFuncao T1 On T0.codFuncao = …Run Code Online (Sandbox Code Playgroud) 我一直在一个表中记录昂贵的运行查询及其查询计划,以便我们监控性能趋势并确定需要优化的区域。
然而,现在已经到了查询计划占用太多空间的地步(因为我们针对每个查询存储整个计划)。
因此,我试图通过将 QueryPlanHash 和 QueryPlan 提取到另一个表来规范化现有数据。
CREATE TABLE QueryPlans
(
QueryPlanHash VARBINARY(25),
QueryPlan XML,
CONSTRAINT PK_QueryPlans PRIMARY KEY
(
QueryPlanHash
)
);
Run Code Online (Sandbox Code Playgroud)
由于query_plan_hashin的定义sys.dm_exec_query_stats是一个二进制字段(并且我会定期插入新数据),因此我使用VARBINARY了新表中的数据类型。
但是,下面的插入失败了...
INSERT INTO QueryPlans
( QueryPlanHash, QueryPlan )
SELECT queryplanhash, queryplan
FROM
(
SELECT
p.value('(./@QueryPlanHash)[1]', 'varchar(20)') queryplanhash,
QueryPlan,
ROW_NUMBER() OVER (PARTITION BY p.value('(./@QueryPlanHash)[1]', 'varchar(20)') ORDER BY DateRecorded) rownum
FROM table
CROSS APPLY QueryPlan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple[@QueryPlanHash]') t(p)
) data
WHERE rownum = 1
Run Code Online (Sandbox Code Playgroud)
....有错误
Implicit conversion from data type varchar to varbinary is …Run Code Online (Sandbox Code Playgroud) 我有一个相当大的表,其中一列是 XML 数据,XML 条目的平均大小约为 15 KB。所有其他列都是常规整数、大整数、GUID 等。为了获得一些具体数字,假设该表有一百万行,大小约为 15 GB。
我注意到的是,如果我想选择所有列,这个表选择数据的速度真的很慢。当我做
SELECT TOP 1000 * FROM TABLE
Run Code Online (Sandbox Code Playgroud)
从磁盘读取数据大约需要 20-25 秒 - 即使我没有对结果强加任何排序。我使用冷缓存(即 after DBCC DROPCLEANBUFFERS)运行查询。IO统计结果如下:
扫描计数 1,逻辑读 364,物理读 24,预读 7191,lob 逻辑读 7924,lob 物理读 1690,lob 预读 3968。
它抓取了大约 15 MB 的数据。执行计划如我所料显示聚集索引扫描。
除了我的查询外,磁盘上没有任何 IO;我还检查了聚集索引碎片是否接近 0%。这是一个消费级 SATA 驱动器,但我仍然认为 SQL Server 能够以比 ~100-150 MB/min 更快的速度扫描表。
XML 字段的存在导致大部分表数据位于 LOB_DATA 页上(实际上约 90% 的表页是 LOB_DATA)。
我想我的问题是 - 我认为 LOB_DATA 页面会导致扫描缓慢不仅是因为它们的大小,还因为当表中有很多 LOB_DATA 页面时,SQL Server 无法有效扫描聚集索引,我是否正确?
更广泛地说 - 拥有这样的表结构/数据模式是否合理?使用 Filestream 的建议通常说明更大的字段大小,所以我真的不想走那条路。我还没有真正找到关于这个特定场景的任何好的信息。
我一直在考虑 XML 压缩,但它需要在客户端或使用 SQLCLR 完成,并且需要在系统中实现相当多的工作。
我尝试了压缩,因为 XML 是高度冗余的,所以我可以(在 …
我正在将一些 XML 数据插入 SQL Server 中的 XML 列,但在插入数据后,它已被 sql server 更改。这是我插入的数据
<xsl:value-of select="name/n/given" />
<xsl:text> </xsl:text>
<xsl:value-of select="name/n/family" />
Run Code Online (Sandbox Code Playgroud)
当我读回来时,它看起来像这样
<xsl:value-of select="name/n/given" />
<xsl:text />
<xsl:value-of select="name/n/family" />
Run Code Online (Sandbox Code Playgroud)
注意第二行。这是一个问题,因为它改变了 XSLT 转换输出的方式。第一个例子将在给定和姓氏之间创建一个空格,而第二个不会创建任何空格,所以它会像约翰约翰森,而第一个会像约翰约翰森。
有没有办法解决这个问题?
我的任务是为我的一位客户发送一份小型月度报告。该报告以前在实例上手动运行,输出复制到电子表格并作为附件发送给客户。
我正在寻找一个更永久的解决方案,所以我打算使用 sp_send_dbmail存储过程来运行查询并将其作为附件发送。
一切正常,但消息的格式。最初我尝试将输出附加为带有 a 的 CSV 文件,@query_result_seperator = ','但结果无处不在!
当我正常运行报告时,输出在 SQL 中看起来不错。但是将其作为 CSV 发送或仅在消息正文中发送则不然。
我认为如果我将输出导出为 HTML 并作为附件/或 XML 发送它可能会更好,但我不知道如何执行此操作。
有没有人有什么建议?
提前致谢!
我正在使用 SQL Server 2008 为一组新资源定义架构...在这种情况下,每条记录(例如行)都需要存储 XML 片段。时; 虽然不经常;我需要查询 XML 以查找元素和属性值。如果留给我自己的设备,我会倾向于使用XML数据类型,尽管我一直认为这是有问题的。所以这让我想到了我的问题。
鉴于这种情况,在尝试决定将 XML 存储在XML列中还是varchar(MAX)列中时,我应该考虑哪些因素
如果有帮助……这里有一些额外的细节:
我在 SQL Server 2008 R2 中创建了一个扩展事件会话。会话运行,并在事件发生时收集事件,正如您所期望的那样。
如果我在事件相对较少的情况下切碎 xml,性能是可以接受的。当我有数千个事件时,需要永远分解 xml。
我知道我做错了什么,我只是没有足够的关于 XML 引擎内部的知识来理解什么。
这是我的扩展事件会话的定义:
IF EXISTS
(
SELECT 1
FROM sys.server_event_sessions dxs
WHERE dxs.name = 'queries'
)
BEGIN
IF EXISTS (
SELECT 1
FROM sys.dm_xe_sessions dxs
WHERE dxs.name = 'queries'
)
BEGIN
ALTER EVENT SESSION queries ON SERVER STATE = STOP;
END
DROP EVENT SESSION queries ON SERVER;
END
CREATE EVENT SESSION queries ON SERVER
ADD EVENT sqlserver.sql_statement_starting
(
ACTION
(
package0.collect_system_time
--, package0.event_sequence
, sqlserver.client_app_name
, sqlserver.client_hostname
--, sqlserver.database_name
, …Run Code Online (Sandbox Code Playgroud) 我有一个这样的 XML 值:
<R>
<I>A</I>
<I>B</I>
<I>C</I>
...
</R>
Run Code Online (Sandbox Code Playgroud)
我想连接所有的I值并返回它们作为单个字符串:ABC...。
现在我知道我可以分解 XML,将结果聚合回无节点 XML,然后应用于.values('text()[1]', ...)结果:
SELECT
(
SELECT
n.n.value('text()[1]', 'varchar(50)') AS [text()]
FROM
@MyXml.nodes('/R/I') AS n (n)
FOR XML
PATH (''),
TYPE
).value('text()[1]', 'varchar(50)')
;
Run Code Online (Sandbox Code Playgroud)
但是,我想仅使用 XPath/XQuery 方法来完成所有这些工作,如下所示:
SELECT @MyXml. ? ( ? );
Run Code Online (Sandbox Code Playgroud)
有这样的方法吗?
我在这个方向寻找解决方案的原因是因为我的实际 XML 也包含其他元素,例如:
SELECT
(
SELECT
n.n.value('text()[1]', 'varchar(50)') AS [text()]
FROM
@MyXml.nodes('/R/I') AS n (n)
FOR XML
PATH (''),
TYPE
).value('text()[1]', 'varchar(50)')
;
Run Code Online (Sandbox Code Playgroud)
而且我希望能够将I值提取为单个字符串,并将J值提取为单个字符串,而不必为每个值使用笨拙的脚本。
xml ×10
sql-server ×9
performance ×2
blob ×1
datatypes ×1
schema ×1
varbinary ×1
varchar ×1
xquery ×1