zoukankan      html  css  js  c++  java
  • SQL Server XML性能优化(Best Practices)

    1. XML数据模型
    XML存储与处理查询的性能取决于数据库的设计与XML数据的结构与粒度。是否要使用XML数据模型,看你

    是不是有半结构化的数据,需要保留文档结构与层次结构的标记语言数据,或可变的结构。

    1.1 标记 Markups
    同样的数据可以以不同的方式来标记,视内容(element值)与元数据信息(attribute值)。越具体的

    element名越易于阅读,且对生成有效的查询计划有帮助。冗长的标记会增加存储的成本。例如:
    a.
    <item type="book"><title>Writing Secure Code</title></item>
    <item type="DVD"><title>The Godfather</title></item>
    如果要查询book,需要写为:/item[@type = "book"]
    b.
    <book><title>Writing Secure Code</title></book>
    <DVD><title>The Godfather</title></DVD>

    如果要查询book,只需要写:/book ,这样效率更高也看起来更简单,而且减少了primary XML index(

    主XML索引)的层数(少了item层)。这就是具体标记(Specific Markups)相对一般标记(Generic

    Markups)的优点。

    对于被类型化的的XML(typed XML),还可以缩减到两层:
    <book title="Writing Secure Code"/>
    <DVD title="The Godfather"/>

    像<DVD><title>The Godfather</title></DVD>这种格式,称为element-centric markup,查询格式

    为/DVD[title = "The Godfather"]
    像<DVD title="The Godfather"/>这种格式,attribute-centric markup,查询格式为/DVD[@title =

    "The Godfather"] ,可以减少一个JOIN。

    1.2 Typed 和 Untyped XML(类型化与非类型化的XML)
    非类型化的XML(untyped XML,没有以XML schema来表示)在SQL Server内部以Unicode字符串的形式存

    储。对他们的操作需要数据转换到相应的类型。例如 (/book/price)[1] > 19.99,会有<price>转换为

    decimal的过程。大量类似的比较就会非常耗资源,这就引出了XML schema中类型信息的重要性。
    类型信息在以下几个方面起作用:
    a. 插入更新的XML数据先被验证是否符合schema,然后以二进制形式存储,方便更快地转换
    b. 类型化的值被存储在XML索引中
    c. 类型化的数据还可以减少范围扫描,例如(/book/price)[1]中的序数[1]在XML schema规定了<price>

    为单值时就是不必要的。

    1.3 属性
    可以使用UDF(用户自定义函数)来获得计算列(computed column)。可以在计算列上添加索引。由于计算列是预计算好的,查询速度更快。
    范例:
    书籍都有ISBN号,把ISBN单独作为计算列的过程如下
    a. 定义获取ISBN号的函数
    CREATE FUNCTION udf_get_book_ISBN (@xData xml) RETURNS varchar(20)
    WITH SCHEMABINDING
    BEGIN
       RETURN @xData.value('(/book/@ISBN)[1]', 'varchar(20)')
    END
    b. 添加计算列
    CREATE TABLE docs (id int PRIMARY KEY, xCol XML)
    ALTER TABLE docs ADD ISBN AS dbo.udf_get_book_ISBN(xCol)
    c. 添加非聚类索引
    CREATE INDEX COMPUTED_IDX ON docs (ISBN)
    d. 写查询
    如果不使用ISBN列,查询如下:
    SELECT xCol
    FROM   docs
    WHERE  xCol.exist ('/book/@ISBN[. = "0-2016-3361-2"]') = 1
    如果使用ISBN列
    SELECT xCol
    FROM   docs
    WHERE  ISBN = '0-2016-3361-2'

    还可以建立属性表(Property Table)

    2. 批量载入XML数据
    --可以使用BCP IN,BULK INSERT和OPENROWSET方法,因为和这次的case无关暂且略过。

    3. XML索引
    3.1 普通索引
    推荐创建初级XML索引(primary XML index),实际上是创建了一个B+树。还可以对于PATH,PROPERTY,VALUE创建次级XML索引(secondary XML indexes)。
    a. PATH索引
    适用于有类似/book[@ISBN = "0-2016-3361-2"]的路径表达式,路径越长越有效
    b. PROPERTY索引
    适用于XML中的多properties查询
    c. VALUE索引
    适用于存在子轴(//操作符)和通配符(类似(/book[@* = "novel"]))的查询
    维护索引的开销也是需要整体考虑的。

    --关于XML部分更新和这次的case无关暂且略过。
    --关于XML全文索引和这次的case无关暂且略过。

    4. 查询优化
    4.1 使用exist()方法来检测是否存在
    尽可能使用exist()来代替value()
    比如如下的查询:
    SELECT *
    FROM   docs
    WHERE    xCol.exist('(/book/title/text())[.="Writing Secure Code"]') = 1

    SELECT *
    FROM   docs
    WHERE  xCol.value('(/book/title)[1]', 'varchar(50)') = 'Writing Secure Code'

    4.2 优化XML blobs(二进制XML)
    更多的tempDB文件可以提供更好的可扩展性。
    减少额外的XML数据类型转换

    4.3 指定Singleton Elements(单件元素)
    对于类型化的XML,默认是singleton的
    非类型化的XML,需要加[1],xCol.query ('/book/title')会被自动转换为xCol.query ('(/book/title)[1]')。

    4.4 对于非类型化的XML的text聚合
    (/book/title[.="Writing Secure Code"])[1]需要聚合<title>下所有的text节点
    如果<title> element只有一个text节点,那么可以使用(/book/title/text())[1][. = "Writing Secure Code"]更有效。

    4.5 将XQuery和XML DML表达式参数化
    XQuery和XML DML不会自动参数化,最好使用sql:column() 或sql:variable() 。

    4.6 序数和预计的优化
    减少语句的分支,如/book[@ISBN = "1-8610-0157-6"]/author/first-name,最好使用/book[author/first-name = "Davis"]这样的格式。
    把序数移到路径的最后,/book[1]/title[1]等同于 (/book/title)[1]
    使用Context Node(上下文节点)
    如下的范例:
    SELECT *
    FROM   docs
    WHERE  xCol.exist ('/book[@subject = "security"]') =  1
    分别对/book和/book/@subject进行了评估,并检测了后者是否包含了值“security”
    如果使用如下表达:
    SELECT *
    FROM   docs
    WHERE  xCol.exist ('/book/@subject[. = "security"]') =  1
    只会对/book/@subject 进行评估

    动态查询与本次的case无关暂且略过。

    具体案例等我做完这个case再详细阐述。

    参考资料:
    Performance Optimizations for the XML Data Type in SQL Server 2005
    http://technet.microsoft.com/en-us/library/ms345118.aspx
    XML Best Practices for Microsoft SQL Server 2005
    http://technet.microsoft.com/en-us/library/ms345115.aspx

  • 相关阅读:
    ASP.NET Web API 2.0 统一响应格式
    [翻译]ASP.NET Web API 2 中的全局错误处理
    【WPF】UserControl 的 Load事件
    解决MS SQL Server 使用HashBytes函数乱码问题
    实例化MD5CryptoServiceProvider报错:此实现不是 Windows 平台 FIPS 验证的加密算法的一部分
    添加扩展方法,提示编译错误 “缺少编译器要求的成员”
    [调试]VS2013调试时提示“运行时当前拒绝计算表达式的值”
    jquery chosen 插件多选初始化
    Asp.net WebForm 中无法引用App_Code文件夹下的类
    文本非法字符过滤 简体转换繁体
  • 原文地址:https://www.cnblogs.com/galaxyyao/p/1442417.html
Copyright © 2011-2022 走看看