表结构如下: uid,rid,name,home,event,data,time
其中 uid 和 rid 联合唯一索引
假如现在表里有接近 100W 行数据,其中每个 uid 大概有 10 行记录
现要查询出单个 uid 下的最大 rid,下面哪个 SQL 语句效率更高呢?
1.SELECT MAX(rid) AS rid FROM table WHERE uid = $1
2.SELECT rid FROM table WHERE uid = $1 ORDER BY rid DESC LIMIT 1
数据库为:PostgreSQL
另外像这样的表结构没有主键性能上会有什么问题吗?(因为主键是用不到的)
![]() 我认为应该是 1 |
![]() 1 |
![]() |
![]() 亲,你有数据直接到数据库里面执行 sql 验证下,比我们验证快多了。。。 |
![]() |
![]() 如果 2 很有用的情况,还发明 MAX 函数搞啥,所以,我站 1 |
![]() |
![]() mysql 肯定是 1 了 |
![]() 在存在(uid, rid)索引的情况下,rid 会按索引排序,两条语句的性能应该是接近的。 |
![]() 一个是最大值,一个是排序,我想除非实现的人抽风了,不然明显最大值的复杂度只有 O(n) |
![]() |
![]() 一样的 ,TOP 1 也是 O(n) |
![]() |
![]() PostgreSQL 的 explain 很强大,别浪费。 |
![]() |
![]() 差不多一样,但是 1 明显更易懂! |
![]() 排序和求最大值复杂度会一样?一个是 O(N2),一个是 On,所以不是很明显吗 |
![]() 我的天那,看了楼上几个回复!!!! |
![]() |
![]() SQL 的优化是数据库帮你完成的,不同的实现可能不同,不过我认为至少存在一个数据库软件这两者是等价的,甚至你写 2 都直接给你优化成 1 实现。 |
![]() |
![]() @sanggao 老哥快别吊胃口了,说说楼上哪里有问题吧 |
![]() 我的天那,看了楼上几个回复!!!! |
![]() |
![]() 就当我口胡吧,似乎两者功能不完全等价。 |
![]() |
![]() @no1xsyzy 好像建立了索引还是,刚没细读,搜不出来的情况 ORDER BY DESC + LIMIT 1 时间很长,用了 JOIN 就 1200ms 以上,写成子查询才保持始终最短时间。 |
![]() |
![]() @glacer 确实是,我往表里插了 100W 数据,有(uid, rid)索引的情况下确实是一样的,差不多都是 38ms 左右 |
![]() |
![]() 看联合索引顺序 |
![]() |
![]() 1. 取某一列的最大值,最小值 |
![]() 感觉是一样的 , uid 确认的情况下 rid 是有序的 , 并不需要再排序 |
![]() |
![]() MYSQL 第一种 |
![]() |
![]() 有索引能命中应该是一样的,没索引应该是 1 快 |
![]() UID,RID 联合索引应该是有顺序的... |
![]() |
![]() 用 explain 看看呢? pg 的 explain 应该可以给出优化后的执行 plan |
![]() 一个字段上有索引的情况下两种执行计划是一致的,如果是无索引(或则楼主这种联合索引 rid 在后的情况下),max ( rid )走全表扫描,order by 这种需要 sort。 |
![]() 与其盲猜,不如用 EXPLAIN ANALYZE 在表上跑一下不就知道了嘛 |
![]() |
![]() 怎么禁用缓存? |
![]() |
![]() 哈,这个楼主如果用的是 SQL 的话我刚测过。160W 条数据,用 MAX 的话是比 DESC LIMIT 1 要快的,大概快十几 MS,不过不确定是不是因为有缓存了才是这样的结果。 |
![]() |
![]() where 部分过滤之后,后续的动作不就是那 10 条记录的操作了么,这有啥好比的。 |
![]() |
![]() 我感觉都差不多,假如要纠结...是不是 limit1 多了一个操作 |