Count(*) 语句的优化问题?

qinjs 2006-08-29 04:04:45
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=0
说明:建立有 ArticleID ,fenlei 索引,isHide 的值只有0和1,没有索引。

语句执行,结果值为2300,执行时间130毫秒,扫描Article 2次,逻辑读 13000次。

而如果只执行
Select count(*) From Article where fenlei=6 and ArticleID<100000
则结果还是2300,执行时间0毫秒,扫描Article 1次,逻辑读 29次。

只是增加了一个isHide=0条件,系统消耗就差别如此大。

请问这个语句,该怎么优化?
...全文
617 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
prcgolf 2006-09-08
  • 打赏
  • 举报
回复
up
hoodlum521 2006-08-30
  • 打赏
  • 举报
回复
Select count(*) From Article where fenlei=6 and ArticleID<100000 and 0 = isHide

这个样呢/??
Oracle 这样效率要高!
qinjs 2006-08-30
  • 打赏
  • 举报
回复
hoodlum521() :
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=0

改为:
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide<1

效率高!
===========================
我这里的运行数据显示不是这样的。

isHide=0的占总数99%以上
那么,

Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=1

Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide>0
的效率都提高了非常多。

如果需要
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=0
的结果,那就变通一下,用
Select count(*) From Article where fenlei=6 and ArticleID<100000的值减去
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=1的值就可以了。
还有个前提是:isHide要建立索引,否则没有优化效果。



不知道哪位高手还有更好的优化办法?
tybeer 2006-08-30
  • 打赏
  • 举报
回复
如果这个表的写入动作较多,在ishide field 建立索引是不适合的,会大大降低系统性能。即便建立索引,在该代码中,性能提高不会很明显。
Linux_9 2006-08-30
  • 打赏
  • 举报
回复
似乎留过名了!
qinjs 2006-08-30
  • 打赏
  • 举报
回复
isHide没有索引时,成本是一样的
qinjs 2006-08-30
  • 打赏
  • 举报
回复
建立了索引,成本对比为
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=0 98.86%

Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=1 1.14%

另外,
Select count(*) From Article where fenlei=6 and ArticleID<100000 and 0 = isHide 没什么效果
suntt 2006-08-30
  • 打赏
  • 举报
回复
仅仅这样分析都是没有头绪的分析,你先看看mssql是采用了如何的执行计划
maxdai 2006-08-30
  • 打赏
  • 举报
回复
如果IsHide的值分布只有两个值,并且0值很多,那么这个索引基本上不会有什么帮助。SQL Server有数据分布的统计数据,成本分析会根据现有的统计来分析是否使用某个索引。象你这种分布甚至大于50%的查询,读index还不如直接scan table了。一般索引只对分布得比较散的数据才有效,除非用clustered索引。
leveretzhang 2006-08-30
  • 打赏
  • 举报
回复
等待邹建!
hoodlum521 2006-08-29
  • 打赏
  • 举报
回复
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=0

改为:
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide<1

效率高!

qinjs 2006-08-29
  • 打赏
  • 举报
回复
不好意思,看反了,查询成本是
isHide=1 49.95%
isHide>0 50.05%
qinjs 2006-08-29
  • 打赏
  • 举报
回复
查询成本对比
isHide>0 49.95%
isHide=1 50.05%
qinjs 2006-08-29
  • 打赏
  • 举报
回复
前面看错了,建立了索引
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=0
表 'Article'。扫描计数 2,逻辑读 193 次,物理读 0 次,预读 0 次。
CPU 时间 = 203 毫秒,耗费时间 = 307 毫秒。

Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=1
表 'Article'。扫描计数 1,逻辑读 168 次,物理读 0 次,预读 0 次。
CPU 时间 = 0 毫秒,耗费时间 = 4 毫秒。

Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide>0表 'Article'。扫描计数 1,逻辑读 152 次,物理读 0 次,预读 0 次。
CPU 时间 = 0 毫秒,耗费时间 = 1 毫秒。



isHide>0 比 isHide=1 还要高效!!!
being21 2006-08-29
  • 打赏
  • 举报
回复
呵呵,学习!!!
specialsoldier 2006-08-29
  • 打赏
  • 举报
回复
--表结构
create table test(num int)
--建立索引前select * from test where num=0
(所影响的行数为 243 行)

表 'test'。扫描计数 1,逻辑读 3239 次,物理读 0 次,预读 0 次。
SET STATISTICS IO on

--建立索引前select * from test where num=1
(所影响的行数为 1916928 行)

表 'test'。扫描计数 1,逻辑读 3239 次,物理读 0 次,预读 0 次。

create index test1 on test(num)

--建立索引后select * from test where num=0
(所影响的行数为 243 行)

表 'test'。扫描计数 1,逻辑读 3 次,物理读 0 次,预读 0 次。--很少数据的0降低了
--建立索引后select * from test where num=1

(所影响的行数为 1916928 行)

表 'test'。扫描计数 1,逻辑读 4272 次,物理读 0 次,预读 0 次。--占绝大多数的1升高了


看来这个效率还得具体情况具体分析啊
qinjs 2006-08-29
  • 打赏
  • 举报
回复
real_name(*真名) :
Select count(isHide) From Article where fenlei=6 and ArticleID<100000 and not isHide
====出错了,把not isHide换成isHide=0,可以运行,但消耗一样没有变化。

specialsoldier(雪地撒野) :
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=1--这里换成1.
===一样的,有索引与没有索引跟isHide=0时的情况一样
specialsoldier 2006-08-29
  • 打赏
  • 举报
回复
那看来是我错了 不好意思 去做点试验~
qinjs 2006-08-29
  • 打赏
  • 举报
回复
是0比1多得多,1很少
这个是文章系统的,1代表该文章被屏蔽用户看不到,这种情况很少
specialsoldier 2006-08-29
  • 打赏
  • 举报
回复
是不是你的0比1少得多?

你试试
Select count(*) From Article where fenlei=6 and ArticleID<100000 and isHide=1--这里换成1.

看看这个的指标
加载更多回复(6)

34,576

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧