最新评论
活跃的毛虫 2012-05-24 16:51
@ideas
你的疑点已经被我排除了,文章中提到:
"select top 10 ID from E_Table where CateParentID=112 之后满怀期待地等了近40+秒...
"
这不是主要原因.主要原因是Scan和Seek的区别
ideas 2012-05-21 10:40
[quote]活跃的毛虫:
[quote]ideas:
拿数据说话,我的测试环境:虚拟机,1G内存,Intel xeon(R) E56006 双核CPU,数据量一千万,无论我怎么样测试,也不会出现楼主所说的那些情况。即使我执行select * from tablename操作,也就是一66883毫秒完成。即使我不建任何索引,执行TOP操作时也是瞬间完成,至于这个为什么,我在上次回复已经说过了。
建议楼主再好好查查原因。[/quote]
嗯,谢谢.
数据行数是一个原因,另外数据列数,各数据列的大小也有原因吧.
我的数据列中有nvarchar(max)的,存放企业简介.不知道是否影响.
这个数据库体积有2....[/quote]
讨论了这么多么,你终于说到重点了“我的数据列中有nvarchar(max)的”。这才是重点,也就是你的查询为什么会慢的根本原因;nvarchar(max)类型的数据,小于8000字节时与普通的varchar(n)是同样的存储方式,也就是行内存储,此时你的数据页就会很多,查询自然会慢;如果大于8000字节时,存储引擎会使用LOB页存储数据,数据页只存储一个16字节的指针,指向真实的数据。找到问题的根源,要解决就简单了。查询的时候不要直接SELECT *然后再分页,要先SELECT ID分布,然后再SELECT *取数据。这样操作,查询计划即使最坏的情况先是索引扫描,再Lookup。这样效率也会提高很多。
j.king 2012-05-15 17:36
这个问题确实值得注意,请问CateParentID是不能为空类型吗?你所查询的数据不足10条,所有把整个表历遍了?
笑东风 2012-05-15 13:15
[quote]活跃的毛虫:
@笑东风
我绝对相信你们的结果会很快,因为很快才是正常的,慢才是不正常.
你说的第二点"碎片过多"好像有这可能.
索引失效和索引建立不对及内存或硬盘不足,都不成立,这个语句在本地双核+2G,服务器至强双核+4G测试结果大同小异.
但数据库的碎片可能性是有的.
另外,亲,这问题拿出来正是想和大家探讨的,这算是一种不厚道么?我也不是吃饱了撑的,为此语句我损失了很多百度收录.
关于慢的结果,你们要不信我帖图给你们看.[/quote]
强烈建议您修改文章后面的结论,将结论改变成探讨语气,免得误导别人,相信你写blog也是为了传播知识吧
活跃的毛虫 2012-05-15 11:31
@海南.胡勇
组合不组合查询是一样的,一开始我还用EF去生成语句,后来发现它生成的语句简直庞大,还慢,最后没办法,只能自己组合语句..
你要读写分开那倒是可行的办法,但我这表在应用中以后只读不写.
活跃的毛虫 2012-05-15 11:04
@魔君六道
Sql Server2008-2012支持你的语法.我的版本才2005
http://msdn.microsoft.com/zh-tw/library/ms187373(v=sql.100).aspx
现成的蛋糕吃不成了.唉
大石头 2012-05-15 10:57
[quote]活跃的毛虫:
@大石头
倒过来倒过去这种做法不科学,倒如1000万数据,那中间的数据怎么办.不能只考虑两头.
而且你不知道你要查询的数据是在前面还是后面.[/quote]
在海量数据分页技术里面,取后面页数据基本都是这样倒过来做。
只是晚上90%以上的分页方案没有提供这个支持而已。
我也没说任何情况都倒过去,你没仔细看我说的
魔君六道 2012-05-15 10:49
@活跃的毛虫
“原因我貌似找到了,如@魔君六道所说,在末端的数据就特别慢,排在前面的数据就很快”
就算排在末端的数据也没关系呀,你用SEEK来代替SCAN嘛,
你要么用你的语句3,要么用我下面的方法,如果你的版本支持的话。
select top 10 * from E_Table WITH (FORCESEEK) where CateParentID=3569
海南.胡勇 2012-05-15 10:41
看到此文,忍不住说几句:
查询效率受影响的原因诸多,你在本地测试,与在服务器上是完全不一样的。
对于几百万的数据,理应不这么慢,用户也忍受不了,当然了,实际需求也是比较复杂的,比较说组合查询,用户要的是组合条件,不可能每个字段都建索引吧,数据量大了效率也就下来了。这类问题处理也比较棘手。俺一般都是把读写库进行分离,以满足不同需求。读上可建大量索引,写的要求就不是太大了。
活跃的毛虫 2012-05-15 10:40
@大石头
倒过来倒过去这种做法不科学,倒如1000万数据,那中间的数据怎么办.不能只考虑两头.
而且你不知道你要查询的数据是在前面还是后面.
活跃的毛虫 2012-05-15 10:39
[quote]ideas:
拿数据说话,我的测试环境:虚拟机,1G内存,Intel xeon(R) E56006 双核CPU,数据量一千万,无论我怎么样测试,也不会出现楼主所说的那些情况。即使我执行select * from tablename操作,也就是一66883毫秒完成。即使我不建任何索引,执行TOP操作时也是瞬间完成,至于这个为什么,我在上次回复已经说过了。
建议楼主再好好查查原因。[/quote]
嗯,谢谢.
数据行数是一个原因,另外数据列数,各数据列的大小也有原因吧.
我的数据列中有nvarchar(max)的,存放企业简介.不知道是否影响.
这个数据库体积有2.244G,这个表是最大的,还包括其它一些零散的数据表如新闻表等,大概几十万数据行.
原因我貌似找到了,如@魔君六道所说,在末端的数据就特别慢,排在前面的数据就很快.
魔君六道 2012-05-15 10:33
[quote]大石头:
@魔君六道
数据在后面导致查询慢,我记得可以倒序查询,得到数据之后再倒过来[/quote]
我不知道啊,我知道SQL SERVER有记录它第一个页面的位置,不过我不清楚SQL SERVER怎么找到最后一页,然后向前也