from:http://blog.csdn.net/tjvictor/article/details/4370771

SQL Server中的XML索引分为两类:主XML 索引和辅助XML索引。其中辅助XML索引又分为:PATH 辅助XML索引,VALUE 辅助XML索引,PROPERTY辅助XML索引。

创建XML索引的语法示例如下:

  1. create table XMLTable(Id int primary key, XMLCol xml);
  2. go
  3. --XML主索引
  4. create primary xml index IPXML_XMLTable_XMLCol on XMLTable(XMLCol);
  5. --XML路径辅助索引
  6. create xml index IXML_XMLTable_XMLCol_Path on XMLTable(XMLCol)
  7. using xml index IPXML_XMLTable_XMLCol for path
  8. --XML属性辅助索引
  9. create xml index IXML_XMLTable_XMLCol_Property on XMLTable(XMLCol)
  10. using xml index IPXML_XMLTable_XMLCol for Property
  11. --XML内容辅助索引
  12. create xml index IXML_XMLTable_XMLCol_value on XMLTable(XMLCol)
  13. using xml index IPXML_XMLTable_XMLCol for value

需要注意是的,建立XML索引的表必须有主键。

建立索引的好处是提高查询效率,坏处是增加存储空间。下面结合实例,说明一下:

1.首先建立测试表,在SSMS中执行如下SQL语句create table XMLTable(Id int primary key, XMLCol xml);建表。

2.下面的程序是给表添加60万条数据,方便测试性能。至于为什么用程序添加而不是用insert语句,请参见我的另一篇博客:SQL Server 批量插入数据的两种方法http://blog.csdn.net/tjvictor/archive/2009/07/18/4360030.aspx

  1. static void Main(string[] args)
  2. {
  3. DataTable dt = GetTableSchema();
  4. for (int count = 1; count <= 600000; count++)
  5. {
  6. DataRow r = dt.NewRow();
  7. r[0] = count;
  8. r[1] = GetPropertyXML();
  9. dt.Rows.Add(r);
  10. }
  11. BulkToDB(dt);
  12. Console.WriteLine("finished");
  13. Console.ReadLine();
  14. }
  15. public static void BulkToDB(DataTable dt)
  16. {
  17. SqlConnection sqlConn = new SqlConnection(
  18. ConfigurationManager.ConnectionStrings["ConnStr1"].ConnectionString);
  19. SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(sqlConn);
  20. sqlBulkCopy.BulkCopyTimeout = 0;
  21. sqlBulkCopy.BatchSize = dt.Rows.Count;
  22. sqlBulkCopy.DestinationTableName = "XMLTable";
  23. try
  24. {
  25. sqlConn.Open();
  26. if (dt != null && dt.Rows.Count != 0)
  27. {
  28. sqlBulkCopy.WriteToServer(dt);
  29. }
  30. }
  31. catch (Exception ex)
  32. {
  33. throw ex;
  34. }
  35. finally
  36. {
  37. sqlConn.Close();
  38. }
  39. }
  40. public static DataTable GetTableSchema()
  41. {
  42. DataTable dt = new DataTable();
  43. dt.Columns.AddRange(new DataColumn[]{
  44. new DataColumn("Id",typeof(int)),
  45. new DataColumn("XMLCol",typeof(string))});
  46. return dt;
  47. }
  48. public static int GetRandRange(int start, int end)
  49. {
  50. Random random = new Random(Guid.NewGuid().GetHashCode());
  51. return random.Next(start, end);
  52. }
  53. public static string GetPropertyXML()
  54. {
  55. StringBuilder buffer = new StringBuilder();
  56. buffer.AppendLine("<TJVICTOR>");
  57. for (int count = 0; count < GetRandRange(1, 10); count++)
  58. {
  59. int baseNum = GetRandRange(1, 100);
  60. buffer.AppendLine(string.Format("<Item{0} v=/"Property{0}/">Value{0}</Item{0}>", baseNum));
  61. }
  62. buffer.AppendLine("</TJVICTOR>");
  63. return buffer.ToString();
  64. }

3.执行一条查询语句,注意它的执行时间和执行计划:

select Id from XMLTable
where XMLCol.exist('/TJVICTOR/Item3')=1

由于机器配置不同,所以执行时间不会完全一样,这里只给出执行计划,以供参考:

所有时间都花在了Table Valued Function上,而且还是clustered index scan。

4.给这个表的XML字段加上索引。

  1. --XML主索引
  2. create primary xml index IPXML_XMLTable_XMLCol on XMLTable(XMLCol);
  3. --XML路径辅助索引
  4. create xml index IXML_XMLTable_XMLCol_Path on XMLTable(XMLCol)
  5. using xml index IPXML_XMLTable_XMLCol for path
  6. --XML属性辅助索引
  7. create xml index IXML_XMLTable_XMLCol_Property on XMLTable(XMLCol)
  8. using xml index IPXML_XMLTable_XMLCol for Property
  9. --XML内容辅助索引
  10. create xml index IXML_XMLTable_XMLCol_value on XMLTable(XMLCol)
  11. using xml index IPXML_XMLTable_XMLCol for value

注意:由于我们表中已经有60万条数据,所以建索引时间会很久,而且会占用大量内存和磁盘,本人就花费了10分钟左右,占了1G内存,和1.3G磁盘。请大家建索引时注意自己的硬盘空间,或者修改前面插入数据的程序,少插入一些数据。

5.重新执行上面的Sql语句:

select Id from XMLTable
where XMLCol.exist('/TJVICTOR/Item3')=1

你会发现,瞬间就出结果了,下面是执行计划,用到了XML index seek。

总结:建立XML索引后,查询效率会大大提高,经过本人的测试,xml.exist的执行效率最高,基本上提高了一个数据级,其它语句比如xml.query,xml.value等,查询速度提高了一倍左右,但总体不是太理想。但同时也发现,xml索引太占空间,比如上面的60万条记录吧,空间占用比例如下:

name       rows           reserved             data              index_size        unused
XMLTable 600000      1479688 KB        160952 KB    1318184 KB      552 KB

关于xml.exist,xml.query,xml.value等基本使用方法,请参考下面的文章:

http://blog.csdn.net/tjvictor/archive/2009/07/21/4368511.aspx

如需转载,请注明本文原创自CSDN TJVictor专栏:

http://blog.csdn.net/tjvictor/archive/2009/07/22/4370771.aspx

SQL Server 2008中如何为XML字段建立索引的更多相关文章

  1. SQL Server 2008中新增的 1.变更数据捕获(CDC) 和 2.更改跟踪

    概述 1.变更数据捕获(CDC)        每一次的数据操作都会记录下来 2.更改跟踪       只会记录最新一条记录   以上两种的区别:         http://blog.csdn.n ...

  2. SQL Server 2008中新增的变更数据捕获(CDC)和更改跟踪

    来源:http://www.cnblogs.com/downmoon/archive/2012/04/10/2439462.html  本文主要介绍SQL Server中记录数据变更的四个方法:触发器 ...

  3. 利用Ring Buffer在SQL Server 2008中进行连接故障排除

    原文:利用Ring Buffer在SQL Server 2008中进行连接故障排除 出自:http://blogs.msdn.com/b/apgcdsd/archive/2011/11/21/ring ...

  4. SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

    SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑 关键词:CDC   原文:http://www.cnblogs.com/chenxizhang/arc ...

  5. SQL Server 2008中的MERGE(不仅仅是合并)

    SQL Server 2008中的MERGE语句能做很多事情,它的功能是根据源表对目标表执行插入.更新或删除操作.最典型的应用就是进行两个表的同步. 下面通过一个简单示例来演示MERGE语句的使用方法 ...

  6. SQL Server 2008中的MERGE(数据同步)

    OK,就像标题呈现的一样,SQL Server 2008中的MERGE语句能做很多事情,它的功能是根据源表对目标表执行插入.更新或删除操作.最典型的应用就是进行两个表的同步. 下面通过一个简单示例来演 ...

  7. SQL SERVER 2008中使用VARBINARY(MAX)进行图像存取的实现方法

          在数据库应用项目开发中,经常会使用一些二进制的图像数据,存储和读取显示图像数据主要采用的是路径链接法和内存流法.路径链接法是将图像文件保存在固定的路径下,数据库中只存储图像文件的路径和名称 ...

  8. SQL Server 2008中的数据压缩

    SQL Server 2008中引入了数据压缩的功能,允许在表.索引和分区中执行数据压缩.这样不仅可以大大节省磁盘的占用空间,还允许将更多数据页装入内存中,从而降低磁 盘IO,提升查询的性能.当然,凡 ...

  9. SQL Server 2008中增强的"汇总"技巧

    本文转载:http://www.cnblogs.com/downmoon/archive/2012/04/06/2433988.html SQL Server 2008中的Pivot和UnPivot: ...

随机推荐

  1. D3.js系列——初步使用、选择元素与绑定数据

    D3 的全称是(Data-Driven Documents),顾名思义可以知道是一个被数据驱动的文档.听名字有点抽象,说简单一点,其实就是一个 JavaScript 的函数库,使用它主要是用来做数据可 ...

  2. Docker解析及轻量级PaaS平台演练(二)--Docker的一些简单命令

    上一篇中,我们对Docker有了一个基本的了解 下面将讨论Docker中Image,Container的相关实际操作 Image管理: 镜像的命名和版本管理: 普通镜像的命名规范 {namespace ...

  3. 【千纸诗书】—— PHP/MySQL二手书网站后台开发之功能实现

    前言:前一篇温习了网站开发需要掌握的基础知识,这一篇重点梳理一下各个功能模块的[详细设计与实现].项目github地址:https://github.com/66Web/php_book_store, ...

  4. jquery ajax/post 请求 案例

    @RequestMapping("/hello")    @ResponseBody    public Hello getJson(HttpServletRequest requ ...

  5. Codeforces 553B Kyoya and Permutation

    problem 题意 本题题意不太easy看懂. 给定一个序列,我们能够把这个序列变成一些循环置换的和.然而这样的置换的方法是不止一种的.我们定义一种standard cyclic represent ...

  6. C中的C文件与h文件辨析(转)

    简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程:       1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成 ...

  7. unity, iOS集成微信

    将微信sdk直接拖进xcode会导致Library Search Paths是错的,需要手动改成如下样子(蓝色选中部分)才能通过编译:

  8. ELF解析(part one)

    the contents class elf { //date structure Elf32_Ehdr ehdr; Elf32_Shdr shdr; Elf32_Phdr phdr; // void ...

  9. MVC的设计模式在JavaWeb中的实现

    JSP开发模式 jsp开发模式的发展 1.模式1:(适合小型项目的技术的开发)     a.第一版本号,纯jsp(封装数据.处理数据,显示数据)     b.第二版本号,Jsp+JavaBean.   ...

  10. SGDMA

    Scatter-gather DMA 使用一个链表描述物理上不连续的存储空间,然后把链表首地址告诉DMA master.DMA master在传输完一块物理连续的数据后,不用发起中断,而是根据链表来传 ...