哈哈哈哈哈哈哈哈哈,终于解决了大富翁一个烦人的性能问题。 (100分)

faint!
soul,你不会以前一直没加索引吧?

另外,有一点你可能需要注意一下,就是sql server的索引优化机制
是如何实现的,我对此不是很清楚,我只能就我使用oracle的体会提醒
你一下,在oracle中使用索引和不使用索引同样性能差别很大,但并不意味
着使用了索引就高枕无忧了.我曾经有一个查询针对它建立了特别的索引,
也跟踪查询计划对sql作了优化,甚至采取了强制优先索引的手段,但速度
仍然不能让人满意,原因是oracle是根据数据在表中的概率分布结合索引
建立情况来制定查询计划的,而这个概率分布是一个静态的结果,因此需要
定期对数据表和索引进行分布情况的分析,这样sql查询器才能制定最优化的
查询计划.

我不知道sql server是否有这样的功能,或者它仅仅只根据索引情况来制定查询
计划,或者它同时依赖于其他某种分析来制定查询计划,我想你应该关注一下,
这对提高性能应该有很大的好处.
 
谢谢soul和孙老师!

——原来不会一直都没有索引吧...
 
掌声响起来!!!
 
以前几乎所有参与查询的字段都添加索引了,这点不会这么傻。
但是组合索引用得非常少。(parent,datetime,status)不是3个索引,是一个组合索引。
只有建立这么一个组合索引象 where parent=0 and status<2 orderby datetime的性能
才能大幅度提高。而不是经过周密的考虑和严格的分析是得不到这个结果的。这样的
情况有很多,大家会发现现在所有的模块都快了,因为我增加了6个类似的组合索引。
最大的一个一下子组合了6个字段。我自己都觉得惊讶,但效果确实非常好。要能得到
这样的结果,必须对sql的索引机制和查询机制非常了解。比如。(status,datetime,parent)
就得不到良好的效果,而按理说,似乎先找到status<2的,再按时间找parent=0的应该
没问题,而事实上是sql检索不是这么做的。他是先查固定值parent,在order datetime,
再检索status。所以得到了这个结果。大家研究下去,sql的奥妙实在是很多的。
 
太好了,我说怎么快多了!
 
就是说的组合索引啊! 组合查询很废时间的,必须建索引。

建议买一本《sql server性能优化》,很薄的一本书,不贵,内容不错。
 
看帖子836663挺不错的。
 
那这里应该还可以优化,应该可以强制指定优先使用status索引,然后排序,
这样效率应该更高.
 
是啊,N年前,我用ORACLE时就有和SOUL一样的体会,那感觉---爽,
其实除了优化分析,还有是合理运用INDEX也很重要。
奇怪的是:这样的问题为什么不发个帖子问问呢?
 
好像是兩三天內的事情......
感覺就是不一樣............
奇怪的是:这样的问题为什么不发个帖子问问呢?
 
又习一课!
 
真是非常好!也非常有趣。

论坛效率最终的解决应该在逻辑结构设计上,而不是在索引或者程序设计上,
如果,我们把主贴和回贴分开为两个表,则可以免去 parent=0
如果,我们有好的 archive 机制,则可以免去 status<2
等等....... 这是我的体会之一。

不过目前的结构倒是让我们体验和获得了数百万条记录处理的宝贵经验。
如何检索到符合一个复合条件并排序的第2000页(每页20条)的记录呢?

soul 的算法:
SELECT ID FROM Letters WHERE id in
(SELECT TOP 20 ID FROM
(SELECT TOP 40000 * FROM Letters
WHERE status<2 and parent=0
ORDER BY [datetime] DESC) as t
ORDER BY [datetime] )
ORDER BY [datetime] DESC

我的算法:
select top 20 Id from letters where Id not in
(select top 39980 Id from letters
where status<2 and parent=0
order by [datetime] desc)
and (status<2 and parent=0)
order by [datetime] desc

仔细分析一番才能发现 soul 的算法是正确的道路,而我在已经很接近真理的时候,
一脚踏到岔路上去了。

谢谢 soul。
 
太好了,谢谢soul和yysun
 
真乃幸事!
 
加了索引后您(yysun)的算法也挺快的。但在页号大的时候比较慢。我发觉主要还
是逻辑太多造成的。所以整了一晚上,整出这么一个东西来。本来想另开一个专题讨
论个问题的。通过这次修改,我也确实感受到当初您的建议是正确的,把帖子和回答
分开也许就不会很慢了。其实我还有一个想法,parent=0 and status<2 这个小于是
关键,如果就是一个字段叫lettertype,然后 lettertype=Q 即是问题的话,也许也
没有这个问题了,也就是说大量数据检索的时候如果牵涉到排序检索,尽量不要用
小于大于的算法,能直接就直接。数据库设计确实是门艺术啊。
 
没有详细规划索引的ms sqlserver数据库是不可想象的,也没有办法用在大数据量的
关键领域,基本上主键会要自动建立clustered index,外键也要建立noclustered index
,where子句后的查询或复合查询字段都要建立索引,但是建立过多的索引会引起,数据
录入insert子句的速度变得缓慢。具体的需求和性能自己取舍了。个人认为,数据库的性
能调优,关键是索引。
 
顶部