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. IP地址转化为32位无符号数

    转自 http://blog.csdn.net/testcs_dn/article/details/38585719 一.将ip地址转成long数值 将IP地址转化成整数的方法如下: 1.通过Stri ...

  2. webmagic 下载页面

    下面是webmagic官方的默认实现HttpClientDownloader中的下载方法. @Override public Page download(Request request, Task t ...

  3. iOS 带IAP提交注意事项及无法submit for review的解决方案

    原地址:http://blog.sina.com.cn/s/blog_71ce775e0101dl4a.html 最近项目接触到了苹果的程序内购(IAP),碰到不少问题,参考了很多帖子才得以解决.在此 ...

  4. LoadRunner中如何验证下载的文件大小、统计下载时间、度量下载速度

    LoadRunner中的web_get_in_property函数可用于返回上一个HTTP请求的相关信息,包括HTTP请求返回码.下载大小.下载时间等: The web_get_int_propert ...

  5. Web前端开发实战1:二级下拉式菜单之CSS实现

    二级下拉式菜单在各大学校站点.电商类站点.新闻类站点等大型?站点非经常见,那么它的实现原理是什么呢? 学习了Web前端开发的知识后,我们是能够实现这种功能的.复杂的都是从基础效果上加入做出来的.原理和 ...

  6. (转)JavaScript: in, hasOwnProperty, delete, for/in

    in 运算符 判断对象是否拥有某一属性只要对象拥有该属性,就会返回true,否则false var point = { x:1, y:1 };alert( 'x' in point );  //tru ...

  7. 关于升级 phpStudy 中 MySQL 版本至 5.7.17

    mysql版本低于5.6 自动更新时间会报错.因此要升级mysql版本.综合网上资料和实际过程中遇到的问题,具体细节和注意事项如下: 1.从官网上下载高版本的 MySQL :https://dev.m ...

  8. Cookie的增删改查

    增加: 第一种方法:Response.Cookies[“UserName”].Value=”张三” Response.Cookies[“UserName”].Expires=DateTime.Now. ...

  9. How to manually remove an infected file from your computer

    http://blog.csdn.net/pipisorry/article/details/41258577 How to manually remove an infected file from ...

  10. TensorFlow学习笔记 速记2 报错:failed call to cuDevicePrimaryCtxRetain: CUDA_ERROR_INVALID_DEVICE

    版本: tensorflow-gpu 原因: 在创建session时没有使用我想让它用的gpu 解决方案: 1. 在python程序中: import os os.environ["CUDA ...