注册 登录
编程论坛 SQL Server论坛

300万条数据,3张表联合查询 select top 8 要8秒多,怎么提高查询效率?

sw4433 发布于 2010-09-17 07:14, 8207 次点击
select top 8 n.id,n.title,n.createTime,c.[name],count(com.id) as comCount,
    c.id as caId
    from news n
    left join category c on n.caId = c.id --inner join速度慢
    left join comment com on com.newsId = n.id
    group by n.id,n.title,n.createTime,c.[name],c.id
    order by comCount desc

总共3张表 news(新闻表),category(分类表),comment(评论表)

-- 100万条数据  2秒多

-- 300万条数据  8秒多

时间有点长,效率态低,怎么解决啊?
13 回复
#2
cnfarer2010-09-17 08:24
1.似乎可以改进这个语句。Group by子句似乎不需要那么项目
2.建立索引(考虑簇集)
#3
cnfarer2010-09-17 08:30
order by comCount desc这样在三表连接后再处理似乎不得不慢。
可以考虑先从comment表来入手,用子查询试试。
#4
gupiao1752010-09-17 15:28
楼主的机子配置不错啊,强悍!

我的845机器,512内存,200万的3表联合查询就可能会当机!更别说300万了。估计一执行就死机!
#5
gupiao1752010-09-17 15:30
注:我的845板不支持512M内存,比较土的杂牌主板,是2根256M的杂牌军组合成512的!
#6
sw44332010-09-17 21:08
建了索引了 title 和 createTime

#7
sw44332010-09-17 21:13
以下是引用cnfarer在2010-9-17 08:30:56的发言:

 order by comCount desc这样在三表连接后再处理似乎不得不慢。
可以考虑先从comment表来入手,用子查询试试。
子查询怎么改?
group by n.id,n.title,n.createTime,c.[name],c.id 这个是必须的啊,少一个就会报错!
#8
sw44332010-09-17 21:14
以下是引用gupiao175在2010-9-17 15:28:50的发言:

楼主的机子配置不错啊,强悍!

我的845机器,512内存,200万的3表联合查询就可能会当机!更别说300万了。估计一执行就死机!
945 3G内存

几百万数据没什么问题,就是时间长点
#9
sw44332010-09-17 21:33
以下是引用cnfarer在2010-9-17 08:30:56的发言:

 order by comCount desc这样在三表连接后再处理似乎不得不慢。
可以考虑先从comment表来入手,用子查询试试。
有类似的sql语句吗?

group by n.id,n.title,n.createTime,c.[name],c.id
    order by comCount desc

group by 。。。是必须的啊
order by comCount desc 我是想根据评论的数量排序啊

有类似的多表查询的实例吗? 要能查询几百万甚至上亿千万数据的
#10
cnfarer2010-09-18 20:41
是不是要找到新闻中评论最多的前8条?!如果是,先从comment表中,找出8个符合条件的newsid,再进行连接查询得到其他项目,这肯定要快得多。
你这个查询语句是先连接再统计,再取前8条,连接的工作量相当大(如果用我的方法,连接工作量要少多少,是很容易比较出来的)。
#11
sw44332010-09-20 09:16
我想查询评论最多 的newsid
select  top 8 com.newsId , count(id) as countId  from comment com
    where not exists(select 1 from comment where newsId = com.newsId and id>com.id)
    group by com.newsId
    order by countId desc
查询结果好像不对

查询评论最多的前几条数据的 newsid,
比如说
newsid :
99451
39
39
46
39
46
99451
99451
99451
99490
1000000
99451
47
47
47
47
47
47
我要的结果:  按评论最多到最少排序
47 (6条评论)
99451 (5条评论)
39 (3条评论)
46 (2条评论)

sql语句应该怎么写?
#12
cnfarer2010-09-20 20:07
试试吧,不知可否?
select n.id,n.title,n.createTime,c.[name],c.id as  caID, from (select top 8 newsid,count(id) as comcount from comment group by newid order by comcount desc) cnt inner join news n on cont.newsid=n.id inner join category c on n.caid=c.id

如果comment表在newsid上有索引news表在caid上有索引!我想对查询效率是会有较大提升的。
#13
cnfarer2010-09-20 20:12
上述语句中当然也可以用left outer join,测试一下,做个对比。希望将结果公示!
#14
sw44332010-09-23 10:43
搞定了!
下面是原来的sql语句:
news(新闻表),category(分类表),comment(评论表) 都与news表有主外键关系
这是原来的sql语句   (查询时间8秒左右,而且 CUP 占用率很高!)
select top 8 n.id,n.title,n.createTime,c.[name],count(com.id) as comCount,
    c.id as caId
    from news n
    left join category c on n.caId = c.id
    left join comment com on com.newsId = n.id
    group by n.id,n.title,n.createTime,c.[name],c.id
    order by comCount desc

这是根据 版主 cnfarer 的建议改进过的sql语句   (查询时1秒不到,接近0秒)
查询前8条评论最多的新闻
select n.id,n.title,n.createTime,c.[name],c.id as caId
    from news n
    left join category c on n.caId = c.id
    where n.id in
    (
        select top 8  newsId from comment com
         group by com.newsId
        order by count(newsid) desc
    )
感谢
版主 cnfarer  !!
1