.net Entity Framework(调研的是Entity Framework 4.0) code first方式生成数据库时,不能修改数据库表的索引,而SQLServer默认会把数据表的主键设置为聚集索引,所以Entity Framework如果要修改索引,只能执行sql脚本修改。

这里主要介绍一下调研修改聚集索引来提升查询性能的过程。

系统环境

  我们做的是一个form程序,多个客户端直接访问数据库。对于此系统,用户没有需求在短时间内插入大量的数据,只需要满足一般的业务需求即可,但是用户需要一些复杂的查询,有些复杂的查询包括了5个表的查询,这5个表的查询中,有三个表的查询条件加起来有30个,而且每个表还有好多模糊查询(主要是为了用户能查询到数据,所以模糊查询还是必须的)。

  我们使用的ORM框架的是.net 的Entity Framework,版本是4.0,开发环境是vs2010,用Entity Framework的code first方式生成数据库,数据库中每张表的主键是无序的GUID。

在开发测试中发现的一些问题

  一个系统随着数据量的增加,性能还是很重要的。所以我们在测试的时候,制造了一些数据,用于平时的性能测试。主要的表有20w数据,5个表加起来有70w左右的数据。在测试时,发现在这个数量级的数据下,有些复杂的查询会很慢(每次查询清理数据库缓存来查询,清理缓存的语句:DBCC freeproccache;DBCC dropcleanbuffers;),有的甚至到了20多秒才能查询出来结果,虽然这个查询不是经常使用的查询,但是对于用户来说,肯定体验不够好,于是就开始调研怎么才能查询快一些。

调研过程

  首先,想到的是手动编写SQL来代替Entity Framework自动生成的SQL,因为Entity Framework自动生成的SQL经过一系列的转化,最后变得很复杂,而且阅读性不够好。于是手动写了几个sql的查询条件的语句,然后在SqlServer管理界面直接执行脚本,查看手写与Entity Framework生成的同样条件的脚本(Entity Framework生成的脚本是用Sql Server Profiler捕捉得到的)查询性能有多大差距。

  得到的结论是手写的脚本比Entity Framework生成的有的提升性能不大,有的反而比Entity Framework生成的还慢了,执行脚本时,也是每次查询都清理数据库缓存。除非对SQL很深入的了解,知道怎么能很好的提升性能,否则自己写的比自动生成的还慢了。对数据库查询比较了解的可以自己尝试一下,看看能不能大幅度提高

其次,查阅了网上关于SQL提升查询性能的文章,大多提到的是设置正确的索引能提升性能,对我帮助很大的是这几个网页:

http://www.cnblogs.com/marvin/p/4123745.html

http://www.cnblogs.com/chenmh/p/3999475.html

http://www.cnblogs.com/zhouruifu/archive/2012/04/18/2454088.html

我发现我们系统生成的数据库,每张表的Id都是聚集索引,都是无序的GUID,于是就想着更改几张表的聚集索引。刚开始我在查找有没有简单的修改索引的方法,可不可以直接删除聚集索引,然后更改其它某个字段为聚集索引,因为好多表与我们查询的主表有关联,有一些外键,所以索引不能直接删除,除非先把这些外键删除,但是删除外键后担心有些表关联查询就会慢了,于是就开始尝试着先删除使用到这几个表主键作为外键的外键,查找要删除的外键很简单,删除表的主键的聚集索引,会提示有还有哪个外键不能删除,如下图所示。

等所有的约束删除后,主键的聚集索引就可以删除了。注意,删除的时候请记住删除了哪些外键,等修改聚集索引后,还需要把这些删除的外键加上,不知道怎么加外键?请查看每个表的Create语句。

然后选择表的某个字段作为聚集索引,之后再把表的Id修改为非聚集索引。

最后,5个表中,三个表修改好聚集索引后,可以测试性能是否有所提高了。

修改索引的脚本写好后,开始在SQL Server的2005和2008上做测试。

以下是我在SQL Server 2008上测试结果

以下是我在SQL Server 2005上测试结果

测试结论

修改索引后,查询速度比不修改索引时快,速度提高了一半以上,但是插入数据时会相对慢一些,虽然慢一些,但是都是在1秒之内,尤其在Sql Server 2008上比较明显。

当然这个提高幅度不是特别大很多,如果数据量再大一些,到了百万级别,也许这个解决方案可能效果不太明显,百万级别的没有进一步测试。

初次写长篇文章,有些数据不便于与大家分享,欢迎大家提意见和建议,如果有更好的方案来提升性能,那就最好不过了。

Entity Framework Code First+SQL Server,改变聚集索引,提高查询性能的更多相关文章

  1. SQL Server-聚焦过滤索引提高查询性能(十)

    前言 这一节我们还是继续讲讲索引知识,前面我们讲了聚集索引.非聚集索引以及覆盖索引等,在这其中还有一个过滤索引,通过索引过滤我们也能提高查询性能,简短的内容,深入的理解,Always to revie ...

  2. SQL Server-聚焦过滤索引提高查询性能

    前言 这一节我们还是继续讲讲索引知识,前面我们讲了聚集索引.非聚集索引以及覆盖索引等,在这其中还有一个过滤索引,通过索引过滤我们也能提高查询性能,简短的内容,深入的理解,Always to revie ...

  3. SQL查询优化:详解SQL Server非聚集索引(转载)

    本文是转载,原文地址 http://tech.it168.com/a2011/1228/1295/000001295176.shtml 在SQL SERVER中,非聚集索引其实可以看作是一个含有聚集索 ...

  4. T-SQL查询高级--理解SQL SERVER中非聚集索引的覆盖,连接,交叉和过滤

      写在前面:这是第一篇T-SQL查询高级系列文章.但是T-SQL查询进阶系列还远远没有写完.这个主题放到高级我想是因为这个主题需要一些进阶的知识作为基础..如果文章中有错误的地方请不吝指正.本篇文章 ...

  5. 但从谈论性能点SQL Server选择聚集索引键

    简单介绍 在SQL Server中,数据是按页进行存放的.而为表加上聚集索引后,SQL Server对于数据的查找就是依照聚集索引的列作为keyword进行了. 因此对于聚集索引的选择对性能的影响就变 ...

  6. SQL Server 非聚集索引的覆盖,连接,交叉和过滤 <第二篇>

    在SQL Server中,非聚集索引其实可以看做是一个含有聚集索引的表,但相对实际的表来说,非聚集索引中所存储的表的列数要少得多,一般就是索引列,聚集键(或RID).非聚集索引仅仅包含源表中的非聚集索 ...

  7. SQL Server的聚集索引和非聚集索引

    微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引.簇集索引)和非聚集索引(nonclustered index,也称非聚类索引.非簇集索引)…… (一) ...

  8. SQL SERVER中非聚集索引的覆盖,连接,交叉,过滤

    1.覆盖索引:select和where中包含的结果集中应存在“非聚集索引列”,这样就不用查找基表了,索引表即可搞定:   2.索引交叉:索引的交叉可以理解成建立多个非聚集索引之间的join,如表实体一 ...

  9. SQL Server 百万级数据提高查询速度的方法

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉 ...

随机推荐

  1. 爱上朴实的CSS细节

    英文原文:Learning to Love the Boring Bits of CSS  未来的CSS太让人兴奋了:一方面,是全新的页面布局方式:另一方面,是酷炫的滤镜.颜色等视觉效果.这些CSS, ...

  2. THINKPHP中几个缓存的问题

    1.字段缓存. THINKPHP是默认开启字段缓存的.如果关闭了APPDEBUG(即在index.php中设置了这样一句话:define("APP_DEBUG","FAL ...

  3. Can you solve this equation?

    Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...

  4. ELK 完整部署和使用 - 每天5分钟玩转 Docker 容器技术(90)

    上一节已经部署了容器化的 ELK,本节讨论如何将日志导入 ELK 并进行图形化展示. 几乎所有的软件和应用都有自己的日志文件,容器也不例外.前面我们已经知道 Docker 会将容器日志记录到 /var ...

  5. 对比jquery获取属性的方法props、attr、data

    1.attr,prop 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法.对于自定义的属性是取不到的: 对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法. 2.a ...

  6. html5 postMessage解决跨域、跨窗口消息传递[转载]

    原文:http://www.cnblogs.com/dolphinX/p/3464056.html 一些麻烦事儿 平时做web开发的时候关于消息传递,除了客户端与服务器传值还有几个经常会遇到的问题 1 ...

  7. :after伪类+content内容生成

    :after伪类+content 清除浮动的影响 浮动元素会让此div的高度塌陷.如下例子: .box{padding:10px; background:gray;} .l{float:left;} ...

  8. HTML学习笔记 CSS表格及轮廓案例 第八节 (原创)参考使用表

    #tb, tb1, tr, th, td { border: 5px solid blue; /*加边框*/ padding: 5px; /*内边距*/ } #tb1 { border-collaps ...

  9. Ruby变量常量

    全局变量:以$开头 实例变量:以@开头  @cust_id=id Ruby 常量: 常量以大写字母开头

  10. java操作solr实现查询功能

    一.封装的查询方法 /** * solr查询方法 * @param client solr客户端 * @param query solr查询对象 * @return list集合 * @throws ...