对于外键及相关键是否比严格的范式型效率高这两张表是显著的胖瘦表查询这种情况也比较常见假设使用严格的范式型表结构也就是News表不存在CateTitle这里进行连接查询selectn.*,c.*fromnews ninnerjoinCate conc.CateIdn.CateIdandc.CateId1执行计划如下个人ASP.NET程序性能优化心得(1)数据库篇外一篇另一种情况查询语句如下select*fromNewswhereCateId1执行计划如下从执行计划里可以看到第一种情况在两次聚焦索引查找后再进行一次嵌套循环将结果合并而第二种情况只有一次聚焦索引扫描因此会在一定程序上减少性能的消耗下图是SQL Server Profiler的对比个人ASP.NET程序性能优化心得(1)数据库篇外一篇这里Reads大致相同由于语句又进行了一次合并去处会对CPU有一定的性能消耗。结论将外键及相关键合并到主表上会在这种简单查询中提升一定的性能但是它却是靠数据冗余来达到提升性能的目的而实际上由于查询条件是在聚集索引上进行的因此如果是数据量不大的情况可以不必考虑这种情况。2、DateTime类型问题上一篇文章我提到了一个观点DateTime比Int性能要高这是很武断的结论而且那个例子里我仅是以排序来去说明。事实上两者类型都是BigInt类型来存储在数据库中的只不过DateTime占用8个字节Int占用4个字节在这种简单的排序中性能基本没有任何差别DateTime具有强大的时间运算函数Int类型当然达不到这些功能这时候使用DateTime是必须的但如果是类似ORDER BY AddTime DESC这种情况假设添加时间默认值是GETDATE()那么这个排序与主键排序应该是一致的这时建议使用ORDER BY NewsID DESC来进行排序。SQL语句如下selecttop5000 *fromNewsorderbyaddtimedescselecttop5000 *fromNewsorderbyNewsIddesc在SQL Server Profiler中执行结果如下因此结论是DateTime类型还是继续保留使用吧如果存储的实际上是SmallDateTime建议还是使用smalldatetime来存储数据。3、SELECT TOP 1问题搞清楚聚集索引就一定会明白这个问题主键一定是聚集索引在聚集索引上进行查询性能其实影响不大下图分别是带TOP 1和不带TOP 1对查询条件在主键上的分析个人ASP.NET程序性能优化心得(1)数据库篇外一篇而在复杂查询条件下我们就需要更多的参数进行查询这个时候条件列往往假设在没有索引的情况下就会进行全表扫描。这个时候性能就会受到影响不使用TOP 1情况下select*fromNewswhereNewsId500000andPostUserNamewalkingp执行计划如下个人ASP.NET程序性能优化心得(1)数据库篇外一篇个人ASP.NET程序性能优化心得(1)数据库篇外一篇使用TOP 1进行条件约束情况下selecttop1 *fromNewswhereNewsId500000andPostUserNamewalkingp可以看到在查询到结果后符合TOP数目即返回了结果这样就节省了全表扫描的时间详情对比如下图因此结论是对于查询不全部在聚集索引上的查询如果仅是需要返回某几条建议采用TOP进行约束这种性能上的差异在嵌套查询IN等会体现得更加明显。4、Hits、UpdateTime字段是否应该从表中分开这类字段属于主表中更新最为频繁的字段频繁对一张大数据量进行更新数据显示会造成性能下降因此在数据量较大时建议将这类数据分离到另一张表中并对该表中逻辑外键列建立索引以提升性能。新表结构如下News(NewsId,NewsTitle,Content,CateId,CateTitle,PostUserId,PostUserName,AddTime,DateNum,CommentNum)//Hits点击数CommentNum评论次数Hits(NewsId,Hits)Cate(CateId,CateTitle)5、外键问题外键问题影响性能是不言的事实我们这里也是主要以性能为最主要考察点当然具体情况其实更要以具体情况来考虑外键是维护数据完整性重要的一个手段在某些应用场合下数据的完整性可能要比性能更加的重要这种情况下建议还是要建立外键。这种性能上的消耗相对于业务上的重要性要小得多另外也可以通过其他优化方式来进行性能的优化。对于互联网应用数据增长极其快速另外设计不合理、编码不严谨等方面都会造成运行中不可预料的问题除了CSDN上那位老湿谁敢保证0 bug相对来讲使用外键的成本要高很多。当然对于企业网站这种小型系统建议还是使用外键最起码可以规范自己的编码规范。6、Scan都是会进行全表扫描吗在物理上SQL Server使用三种方法来组织其分区中的数据1、用B树存储有聚集索引的表数据页2、使用堆来存储没有存储组织的表3、非聚集索引使用与聚集索引相类似的B树来存储索引结构。针对这三种不同结构SQL Server使用的数据检索方法也会不一样这其实已经是一个相当深奥的知识点了我本人现在也是一知半角上图来自《Microsoft SQL Server企业级平台管理实践》一书结论如下SCAN并非都会进行全表扫描在某些情况下Scan并非比Seek性能差。想要完全搞明白它需要更清楚SQL Server核心的一些查询机制。但是值得注意的是一般情况下我们的查询以简单查询为主这种情况下要尽量避免Scan尤其是类似多重嵌套查询这种复杂的场景。7、见识索引的强大索引的概念相信不用我来讲了下面以实例来说明索引的强大作用。首先是在不建立索引的情况下对CommentNum(评论次数)进行倒序排序selecttop5000 *fromNewsorderbyCommentNumdesc然后对CommentNum建立索引重新执行SQL语句