表结构
serial_no user_id O_datetime NOTE
1 F001 2012-05-04 14:10
2 F001 2012-05-06 10:00
3 F001 2012-05-04 12:10
4 F004 2012-05-02 10:15
5 F001 2012-05-04 14:10
6 D002 2012-05-01 09:00
7 F001 2012-05-05 10:00
8 F001 2012-05-06 10:00
9 F001 2012-05-01 09:00serial_no是自增列
我要得到user_id分组o_datetime是最大的的一条记录
我目前使用的是
select * from tab1 as t where serial_no=(select top 1 serial_no from tab1 where t.user_id=user_id order by o_datetime desc)
查询速度效果很差
如果使用max(o_datetime)会出现二条记录,因为有时间是相同的
serial_no user_id O_datetime NOTE
1 F001 2012-05-04 14:10
2 F001 2012-05-06 10:00
3 F001 2012-05-04 12:10
4 F004 2012-05-02 10:15
5 F001 2012-05-04 14:10
6 D002 2012-05-01 09:00
7 F001 2012-05-05 10:00
8 F001 2012-05-06 10:00
9 F001 2012-05-01 09:00serial_no是自增列
我要得到user_id分组o_datetime是最大的的一条记录
我目前使用的是
select * from tab1 as t where serial_no=(select top 1 serial_no from tab1 where t.user_id=user_id order by o_datetime desc)
查询速度效果很差
如果使用max(o_datetime)会出现二条记录,因为有时间是相同的
解决方案 »
- MSSQL2008中多个客户端同时Update同一张表出现死锁的问题!
- sql查询出最近一周内每天的总数
- fedora 14 自带的mysql的头文件在哪?
- 请问下,数据库中的union的用法
- 这两句SQL语句的效果是不是一样?
- 求检查不同行的数据之两列值是否一致的方法
- 关于IP地址数据库的问题,各位大侠进来帮一下小弟!谢谢
- 请问SqlServer 2000中,全文索引中可否查找中文?
- 在分析服务器中看分析数据时,出错Provider cannot be found. It may not be properly installed.是什么原因呢?
- Sql-server 2005 sp3补丁包安装问题
- sql server 在同一表下覆盖一段时间当中的一列数据。。
- 关于复制,我有一个数据库Db1需要复制N个表,要求复制的实效性不同,发布一个复制完成所有或发布多个复制来完成,哪个更好呢?
go
create table [TB] (serial_no int,user_id nvarchar(8),O_datetime datetime,NOTE sql_variant)
insert into [TB]
select 1,'F001','2012-05-04 14:10',null union all
select 2,'F001','2012-05-06 10:00',null union all
select 3,'F001','2012-05-04 12:10',null union all
select 4,'F004','2012-05-02 10:15',null union all
select 5,'F001','2012-05-04 14:10',null union all
select 6,'D002','2012-05-01 09:00',null union all
select 7,'F001','2012-05-05 10:00',null union all
select 8,'F001','2012-05-06 10:00',null union all
select 9,'F001','2012-05-01 09:00',nullselect * from [TB]
select distinct B.user_id,B.O_datetime
from TB a
cross apply(select top 1 user_id,O_datetime
from TB
where a.user_id = user_id order by O_datetime desc)B
from TB
where a.user_id = user_id order by O_datetime desc
这种查询方式效果很差
并且 还有一个NOTE列,这儿存储 的一些字符串信息,所以这二列是不相同的
select distinct B.user_id,B.O_datetime
from TB a
cross apply(select top 1 user_id,O_datetime
from TB
where a.user_id = user_id order by O_datetime desc)B我还有一个NOTE,这儿存储 的是字符,不同的,所以使用distinct没有任何意义
LZ贴下执行计划看看到底是什么地方慢了,Ctrl+L
2005版本往上推荐使用cross apply来处理分组top的问题,之前也实际测试过,应该算较为优化的方法了。
from TB
where user_id ='AAA'
order by O_datetime desc
LZ 看看这个语句的执行计划,看看走没走索引。听起来感觉你这个慢的问题,貌似是没走索引闹的。
如果是数据量很大的话,建议使用分区表,分区索引的方式
聚集索引扫描?
scan的话性能不高。LZ尝试下将上述要选定的3个列 user_id,O_datetime ,note 建立一个覆盖索引。
这样应该可以使用到 index seek ,效率应该会有所提高。100多万的数据量还好啊。之前top1 的语句用了多长时间呢?应该不至于会慢的厉害的。
可是 “如果使用max(o_datetime)会出现二条记录,因为有时间是相同的”
“并且 还有一个NOTE列,这儿存储 的一些字符串信息,所以这二列是不相同的”
这根本就是矛盾的吗。比如 同一个 o_datetime 值 有多条记录, 怎么区分要哪个?请给出规则啊
user_id 和 O_datetime 这两列上有没有索引?
在这两个上面分别建立非聚集索引 然后再试试
select *
from tb a
where not exists (select 1 from tb b
where b.user_id=a.user_id and b.O_datetime>a.O_datetime)