Sql server SQL Server 2008-手动解析XML,还是为XML字段使用内置的XML索引?

Sql server SQL Server 2008-手动解析XML,还是为XML字段使用内置的XML索引?,sql-server,xml,sql-server-2008,Sql Server,Xml,Sql Server 2008,我正在SQL Server 2008中开发一个日志数据库。它将主要由一个表组成,如下所示: StepLog ---------------- StepLogID ClientID LogContent XML CreateDate 基本上,这个表中发生的事情是,不同的客户机将把某些活动记录到这个表中。LogContent字段将是XML非类型的,因为我们不知道客户端想要记录什么 为了允许搜索LogContent字段,当前的计划是以编程方式拆分LogContent字段。用于分

我正在SQL Server 2008中开发一个日志数据库。它将主要由一个表组成,如下所示:

StepLog 
----------------
  StepLogID
  ClientID
  LogContent   XML
  CreateDate
基本上,这个表中发生的事情是,不同的客户机将把某些活动记录到这个表中。LogContent字段将是XML非类型的,因为我们不知道客户端想要记录什么

为了允许搜索LogContent字段,当前的计划是以编程方式拆分LogContent字段。用于分解的元数据将位于如下表中:

XPathAttribute
----------------
  XPathAttributeID
  AttributeName
  AttributeDescription
  XPath
在StepLog中插入一条记录后,我们将有一个存储过程,它将获取XPathAttribute中定义的所有XPath,并将它们写入另一个表XPathAttributeValue

XPathAttributeValue
----------------
  XPathAttributeValueID
  StepLogID
  AttributeID
  AttributeValue 
在研究这个设计时,我最初的想法是,为什么不使用XML索引,包括主索引和辅助索引?这将避免我们方面的大量工作,并使用内置功能

我对XML索引没有太多的经验,而最初的设计人员在SQL Server 2005中对XML索引的性能有一些糟糕的经验,这就是这个设计的起源

非常感谢您的反馈

谢谢,
Sylvia

XML索引在特定场景中有帮助,如中所述:

以下是一些指导原则 正在创建一个或多个辅助对象 索引:

如果您的工作负载在XML上大量使用路径表达式 列,路径二级XML索引 可能会加快你的工作量。 最常见的情况是使用 中XML列上的exist方法 Transact-SQL的WHERE子句。 如果您的工作负载从单个XML检索多个值 通过使用路径表达式, 每个XML中的群集路径 属性索引中的实例可能是 有用的这种情况通常是 在属性包场景中发生 获取对象的属性 它的主键值是已知的。 如果您的工作负载涉及查询XML中的值 不知道元素的实例 或包含这些属性的属性名称 值,则可能需要创建 价值指数。这通常会发生 使用后代轴查找,例如 //作者[姓=霍华德],在哪里 元素可以在任何时间发生 层次结构的级别。它也会发生 在通配符查询中,例如/book[@* =novel],其中查询查找具有 具有新颖价值的属性。 如您所见,每种类型的索引都适用于特定的场景。对于像您的项目这样的开放式方法,很难判断哪些索引有用,哪些没有

另一个要考虑的是,如果XML可以为该列声明XML模式,则效果要好得多,但是项目的性质不允许这样做。p>


所以总的来说我想说。。。测量并查看。分解XML并将值存储在关系表中很可能比原始XML访问提高性能。但是,如果您知道模式并分解出一组特定的信息,然后对这些信息进行适当的索引,那么这将适用。现在,即使您分割出一些信息,您也会将其分割成基本上是EAV结构的部分,这很难查询和优化。我还建议您阅读一些关于EAV缺点的讨论,以及如何避免一些问题。

XML索引在特定场景中有帮助,如中所述:

以下是一些指导原则 正在创建一个或多个辅助对象 索引:

如果您的工作负载在XML上大量使用路径表达式 列,路径二级XML索引 可能会加快你的工作量。 最常见的情况是使用 中XML列上的exist方法 Transact-SQL的WHERE子句。 如果您的工作负载从单个XML检索多个值 通过使用路径表达式, 每个XML中的群集路径 属性索引中的实例可能是 有用的这种情况通常是 在属性包场景中发生 获取对象的属性 它的主键值是已知的。 如果您的工作负载涉及查询XML中的值 不知道元素的实例 或包含这些属性的属性名称 值,则可能需要创建 价值指数。这通常会发生 使用后代轴查找,例如 //作者[姓=霍华德],在哪里 元素可以在任何时间发生 层次结构的级别。它也会发生 在通配符查询中,例如/book[@* =novel],其中查询查找具有 具有新颖价值的属性。 如您所见,每种类型的索引都适用于特定的场景。对于像您的项目这样的开放式方法,很难判断哪些索引有用,哪些没有

另一个要考虑的是,如果XML可以为该列声明XML模式,那么XML会做得更好,但是 e项目的性质不允许这样做


所以总的来说我想说。。。测量并查看。分解XML并将值存储在关系表中很可能比原始XML访问提高性能。但是,如果您知道模式并分解出一组特定的信息,然后对这些信息进行适当的索引,那么这将适用。现在,即使您分割出一些信息,您也会将其分割成基本上是EAV结构的部分,这很难查询和优化。我还建议您仔细阅读有关EAV缺点以及如何避免一些问题的讨论。

我基本上同意@Remus所说的

也就是说,一定要使用内置的XML索引。SQLServer非常好地处理了大量XML集合。你自己翻滚所节省的时间将是无法估量的


我要提到一件事——添加一个模式。我希望它能帮助查询优化器,但它没有,所以我就把它忘了。你说它是非类型的,所以这不应该出现。

我基本上同意@Remus所说的

也就是说,一定要使用内置的XML索引。SQLServer非常好地处理了大量XML集合。你自己翻滚所节省的时间将是无法估量的


我要提到一件事——添加一个模式。我希望它能帮助查询优化器,但它没有,所以我就把它忘了。您说过它是非类型化的,所以不应该出现这种情况。

我的理解是,XML索引应该有助于检索。但是它们占用了大量的空间资源。XML索引确实有效,并且确实加快了访问速度——但是,它们占用了大量的磁盘空间!我们的数据库使用XML索引从1GB扩展到11GB。。。。最后,我们使用存储函数和持久化计算列将最常用的项呈现到包含XML的表中。在不占用大量空间的情况下,快速查询那些常用项目…@marc_s-感谢您的评论!我很好奇-当你说你浮出水面的项目-你的意思是你真的把它们解析成一个单独的列或计算列在表中?然后-您是否从xml字段中删除了它们?因为如果不从XML字段中删除它们,空间问题仍然会存在,对吗?是的,我们使用存储函数使一些XML元素在实际表中作为计算列可见。它们没有从XML中删除——因此,是的,XML中的数据空间仍然被使用——但我们不需要任何XML索引,而这正是我们在磁盘方面的巨大成本space@marc_s-我明白了,再次感谢!我的理解是,XML索引应该有助于检索。但是它们占用了大量的空间资源。XML索引确实有效,并且确实加快了访问速度——但是,它们占用了大量的磁盘空间!我们的数据库使用XML索引从1GB扩展到11GB。。。。最后,我们使用存储函数和持久化计算列将最常用的项呈现到包含XML的表中。在不占用大量空间的情况下,快速查询那些常用项目…@marc_s-感谢您的评论!我很好奇-当你说你浮出水面的项目-你的意思是你真的把它们解析成一个单独的列或计算列在表中?然后-您是否从xml字段中删除了它们?因为如果不从XML字段中删除它们,空间问题仍然会存在,对吗?是的,我们使用存储函数使一些XML元素在实际表中作为计算列可见。它们没有从XML中删除——因此,是的,XML中的数据空间仍然被使用——但我们不需要任何XML索引,而这正是我们在磁盘方面的巨大成本space@marc_s-我明白了,再次感谢!谢谢你的全面回复!我特别欣赏指向EAV结构缺陷的指针,这篇文章也很有用。EAV上的维基百科条目也很有趣。感谢您的全面回复!我特别欣赏指向EAV结构缺陷的指针,这篇文章也很有用。关于EAV的维基百科条目也很有趣。