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. http://blog.sina.com.cn/s/blog_62e1faba010147k4.html

    http://blog.sina.com.cn/s/blog_62e1faba010147k4.html

  2. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-报错0X4650,18000错误怎么办

    驱动器未就绪错误,请重启驱动器 注意,即便是报这个错,仍然有可能上电成功,这样的话可以直接在TwinCAT中清除错误即可     更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http: ...

  3. javascript 和 jquery 博客

    http://www.cnblogs.com/starof/category/626164.html

  4. SSH框架阶段 ——SSH的优缺点,使用场景?

    Hibernate优点: (1) 对象/关系数据库映射(ORM)它使用时只需要操纵对象,使开发更对象化,抛弃了数据库中心的思想,完全的面向对象思想(2) 透明持久化(persistent)带有持久化状 ...

  5. 10、驱动中的阻塞与非阻塞IO

        阻塞,就是在获取资源的时候,不能获取到,那么就会将当前的进程挂起(睡眠,也就是将当前进程从调度器拿走了,不会调度当前进程),直到满足条件为止再进行操作.相反,非阻塞,就是即使不能获取到资源,非 ...

  6. Spring 集成hibernate时配置连接释放模式

    http://zmfkplj.iteye.com/blog/220822 程序出现一个奇怪的现象,用Quartz作业调度启动任务,运行一段时间后,任务会卡在一个查询接口处,久久不能运行完毕. 我本能的 ...

  7. unity, 内存profile,ImageEffects Temp和Unity GI SystemTex RGBM

    最近用unity的Profiler对公司项目进行内存profile,发现一些问题,记录一下. 用Memory Area的Detailed View,用法见:http://docs.unity3d.co ...

  8. 恩布企业 IM iOS端 1.1 公布, 开源手机 IM

    恩布企业IM的 iOS 苹果开源手机client EntboostChat 公布 1.1 开发版本号.开源企业IM.企业即时通讯软件: 主要更新内容: 录界面添加自己定义LOGO显示 持部门.群组.联 ...

  9. socket编程之多次收发数据

    客户端: #-*- coding:utf-8 -*- #客户端程序 import socket client = socket.socket() #1.创建一个客户端对象 client.connect ...

  10. Swift 烧脑体操一

    Swift 烧脑体操(一) - Optional 的嵌套   前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融 ...