下策 -- 查询出结果后将时间排序后取第一条
- select * from a
- where create_time<="2017-03-29 19:30:36"
- order by create_time desc
- limit 1
这样做虽然可以取出当前时间最近的一条记录, 但是一次查询需要将表遍历一遍, 对于百万以上数据查询将比较费时; limit 是先取出全部结果, 然后取第一条, 相当于查询中占用了不必要的时间和空间; 还有如果需要批量取出最近一条记录, 比方说:"一个订单表, 有用户, 订单时间, 金额, 需要一次性查询所有用户的最近的一条订单记录", 那么每个用户一次查询就要做一次整表的遍历, 数据大的情况下, 时间将会以指数形式增长, 不能投入实际使用.
中策 -- 查询排序后 group by
- select * from (
- select * from a
- where create_time<="2017-03-29 19:30:36"
- order by create_time desc
- ) group by user_id
后来发现使用 group by 可以根据 group by 的参数列分组, 但返回的结果只有一条, 仔细观察发现 group by 是将分组后的第一条记录返回. 时间在查询后默认是顺序排列, 因此需要先将时间倒序排列, 方可取出距离当前最近一条.
这样查询实际上还是进行了两次查询, 虽然时间上相比第一个方法有了质的飞跃, 但是还可以进一步优化.
上策 -- 将 max() 方法和 group by 结合使用
- select *,max(create_time) from a
- where create_time<="2017-03-29 19:30:36"
- group by user_id
这句可以理解为将结果集根据 user_id 分组, 每组取 time 最大一条记录. 这样就很好的实现了批量查询最近记录, 并且仅仅需要遍历一次表, 即使在数据量巨大的情况下也可以在很短的时间查出结果.
扩展:
现在有一张资产设备表: base_assets_turn
查询资产的最新保管人
注: 假设资产编号 ASSETS_ID=254
下策:
- select * from base_assets_turn
- where ASSETS_ID = 254
- order by create_time desc
- limit 1
中策:
- select * from ( select * from base_assets_turn
- where ASSETS_ID = 254
- order by create_time desc) tt GROUP BY tt.ASSETS_ID;
上策:
那么上策该如何书写呢, 欢迎留言
by: 一只阿木木
来源: https://www.cnblogs.com/yizhiamumu/p/9090193.html