大数据量获取记录总数

longchong 2009-09-16 03:54:30
有一张UserMsg,用户短信表,里面msgid,Title,Msg,toUser,fromUser,isRead字段,
toUser,fromUser有建立索引
获取某用的短信时,我用select count(0) from UserMsg where toUser=@toUser
数据还可以,但要获取某用户的未读短信的时候,我用 select count(0) from UserMsg where toUser=@toUser and isRead=0
速度就慢多了。isRead,没有建立索引。这个字段 不是0,就是1,建立索引网上看,这样的值不适合建立索引。同样,感觉维护成本也比较大。

UserMsg表数据在千万级别,大家认为有要怎么来出来比较好。
...全文
278 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
UP
zhang21cnboy 2009-10-10
  • 打赏
  • 举报
回复
呵呵,我不是高手,所以随便说说,希望对你有用。
zhang21cnboy 2009-10-10
  • 打赏
  • 举报
回复
你只说了快慢,没说快的时候要多久?慢的时候要多久?

count()括号里面指定主键,不要count(*)。如果速度还是跟不上,那就需要从以下几个方面着手。

第一个,升级硬件,千万级的数据,如果你的硬件不好,那就不光是这一个查询慢的问题了。

第二,如果硬件确实穷的搞不起(呵呵,咱都是穷人),那就拆分表,库,让每个表的数据不超过100万。

第三,拆分表库要改程序?麻烦?那就启动一个独立的进程,把这样的统计每隔一段时间(1小时?一天?,看你们统计的频率了)执行一次,然后写到一个表中,然后你查询的时候就去查那个表吧。(注意,不是在数据插入,更新的时候同步搞这种事情)。

qihjn 2009-10-10
  • 打赏
  • 举报
回复
都是牛人啊!
longchong 2009-09-25
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 z1g2w3i4 的回复:]
获取某用的短信时,我用select count(0) from UserMsg where toUser=@toUser
数据还可以,但要获取某用户的未读短信的时候,我用 select count(0) from UserMsg where toUser=@toUser and isRead=0
>听楼主的描述,第一个语句不慢,但第二的明显慢了.那你把and前后的条件换一下位置,再试试.提醒楼主,sql语句是从右向左解析的,按从右向左的条件过滤.你可以试试。不行的话只好用索引,或采取以上的方案了
[/Quote]
数据库有自己的优化方案的,你换与不换,一个样。
z1g2w3i4 2009-09-19
  • 打赏
  • 举报
回复
获取某用的短信时,我用select count(0) from UserMsg where toUser=@toUser
数据还可以,但要获取某用户的未读短信的时候,我用 select count(0) from UserMsg where toUser=@toUser and isRead=0
>听楼主的描述,第一个语句不慢,但第二的明显慢了.那你把and前后的条件换一下位置,再试试.提醒楼主,sql语句是从右向左解析的,按从右向左的条件过滤.你可以试试。不行的话只好用索引,或采取以上的方案了
rumlee 2009-09-19
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 z1g2w3i4 的回复:]
获取某用的短信时,我用select count(0) from UserMsg where toUser=@toUser
数据还可以,但要获取某用户的未读短信的时候,我用 select count(0) from UserMsg where toUser=@toUser and isRead=0
>听楼主的描述,第一个语句不慢,但第二的明显慢了.那你把and前后的条件换一下位置,再试试.提醒楼主,sql语句是从右向左解析的,按从右向左的条件过滤.你可以试试。不行的话只好用索引,或采取以上的方案了
[/Quote]

sql语句的where条件并不一定是从左向右或者从右向左,而是一般数据库系统都有一套自己的优化方案,根据索引设置的不同而不同。
showjim 2009-09-18
  • 打赏
  • 举报
回复
像这种统计性质的东西,如果查询比较多的话,应该在User表里面扩展相关统计字段做实时更新.
因为如果有修改统计数据的话,一定是有UserMsg的操作,而User表的操作相对于UserMsg这种大数据量表的操作,打个比方:就好像大人带小孩上车一样,既然大小都上车了,多上个小孩就不显得那么重要了.
rumlee 2009-09-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 longchong 的回复:]
感谢两位的回答。
to:rumlee
一个人的短信,怎么可能只有1,2千呢,都在几十万。你试试在几十万的时候,一个字段没有建立索引的情况下。
to:svjie
字段是tinyint型的,但不是布尔型,因为这字段还是有好几种状态的。

CSND里面没有高手了吗?还是高手都不愿意出来帮助别人。哎!感觉CSND是一年不如一年了。一个问题抛出来,都没有什么人出来回答。
[/Quote]

有几十万的数据量想提高效率,要么只能独立出一个表来,更新的时候更新这个表,如果更新太频繁,那也就只能把touser和iread建联合索引,没有其它的办法了。
rumlee 2009-09-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sbwwkmyd 的回复:]
如果仅仅只有这两条查询语句,并且toUser的值能够空出一个bit位来(支持的用户数量减半)的话,可以考虑将toUser与isRead合并(toUser左移1位让给isRead),
第1条语句可以改为
select count(0) from UserMsg where toUser between @toUser*2 and @toUser*2+1
第2条语句可以改为
select count(0) from UserMsg where toUser=@toUser*2

上面只是一种假设情况,不一定能适合你的情况.
[/Quote]


这个做法其实和建联合索引效果是一样的,但是更新isread就麻烦多了,所以我觉得这个想法确实很好,但是实际应用不可取。这样做不如建一个联合索引。
svjie 2009-09-17
  • 打赏
  • 举报
回复

是不是数据类型转换的原因 ?

isRead 是什么数据类型 ? 如果是 varchar 等类型, 就应该写为 isRead='0'

如果表中数据量少, 速度应该不慢的.
数据量多, 则每条数据的某字段都要进行数据转换就慢了.
rumlee 2009-09-17
  • 打赏
  • 举报
回复
要看你这个数据是怎么进去的,如果是慢慢积累着进去的,可以做一张表,两个字段(touser,msgcount),每次新增或者删除的时候操作这个表,这样查询就快多了。

如果数据更新量很快,那显然上面这个方法就不适合了,也可以考虑将touser和isread两个建联合索引。其实按道理即使isread没有建立索引,touser建立了索引了,应该查询也不会太慢啊。因为满足touser条件的应该不会太多了吧,如果满足touser的1000条的话,需要匹配isread的就只需要匹配1000次就可以了,应该还是比较快的。
showjim 2009-09-17
  • 打赏
  • 举报
回复
如果仅仅只有这两条查询语句,并且toUser的值能够空出一个bit位来(支持的用户数量减半)的话,可以考虑将toUser与isRead合并(toUser左移1位让给isRead),
第1条语句可以改为
select count(0) from UserMsg where toUser between @toUser*2 and @toUser*2+1
第2条语句可以改为
select count(0) from UserMsg where toUser=@toUser*2

上面只是一种假设情况,不一定能适合你的情况.
showjim 2009-09-17
  • 打赏
  • 举报
回复
不适合建立索引应该是针对数据量小的情况下吧,再说优化操作是针对于查询的,也就是针对是实际应用的.
对于大数据量来说,没有什么简单的规则可以直接死搬硬套的.
longchong 2009-09-17
  • 打赏
  • 举报
回复
感谢两位的回答。
to:rumlee
一个人的短信,怎么可能只有1,2千呢,都在几十万。你试试在几十万的时候,一个字段没有建立索引的情况下。
to:svjie
字段是tinyint型的,但不是布尔型,因为这字段还是有好几种状态的。

CSND里面没有高手了吗?还是高手都不愿意出来帮助别人。哎!感觉CSND是一年不如一年了。一个问题抛出来,都没有什么人出来回答。

25,985

社区成员

发帖
与我相关
我的任务
社区描述
高性能WEB开发
社区管理员
  • 高性能WEB开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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