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. go get 下载的包放在哪里呢?

    有些问题,我以前都是似懂非懂,没有去弄个究竟!!!!! 这个习惯非常不好,搞得有些东西看似懂了,又不能百分之百说自己懂了,可能下次就弄不出来了,这样是不可取的. 不能有这种做事的风格. ------- ...

  2. Mac上安装使用Nginx

    1.brew search nginx 2.brew install nginx 启动nginx ,sudo nginx ;访问localhost:8080 发现已出现nginx的欢迎页面了. 备注: ...

  3. Wix 安装部署教程 -CustomAction的七种用法

    在WIX中,CustomAction用来在安装过程中执行自定义行为.比如注册.修改文件.触发其他可执行文件等.这一节主要是介绍一下CustomAction的7种用法. 在此之前要了解InstallEx ...

  4. Microsoft.VisualC 命名空间包含支持用 c + + 语言的代码生成和编译的类。 混合编程中使用COM接口指针

    Microsoft.VisualC 命名空间包含支持用 c + + 语言的代码生成和编译的类. Microsoft.VisualC.StlClr Unmanaged Code 和 Managed Co ...

  5. HTTP——代理协议 HTTP/1.1的CONNECT方法

    我们平时使用HTTP协议无非就是GET.POST这些方法,但是HTTP的内容远不止那些.今天就来说说HTTP代理使用的CONNECT.这个不是在网页开发上用的,如果没兴趣就跳过吧. APACHE只是作 ...

  6. java注解说明

    * 元注解@Target,@Retention,@Documented,@Inherited * * @Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括: * Elem ...

  7. svn命令行版本回滚

    下面以版本号2011回滚到2010为例,在命令行输入: svn merge --dry-run -r 2011:2010 http://my.repository.com/my/project/tru ...

  8. SDRAM驱动篇之简易SDRAM控制器的verilog代码实现

    在Kevin写的上一篇博文<SDRAM理论篇之基础知识及操作时序>中,已经把SDRAM工作的基本原理和SDRAM初始化.读.写及自动刷新操作的时序讲清楚了,在这一片博文中,Kevin来根据 ...

  9. JMX简单样例

    一:创建maven项目,在pom.xml里面增加例如以下依赖 <dependency> <groupId>com.sun.jdmk</groupId> <ar ...

  10. gcc -M -MM -MQ -MF -MT -MD

    静态模式规则对一个较大工程的管理非常有用.它可以对整个工程的同一类文件的重建规则进行一次定义,而实现对整个工程中此类文件指定相同的重建规则.比如,可以用来描述整个工程中所有的.o 文件的依赖规则和编译 ...