2016-09-23 62 views
1

我需要从用户表中获取最新用户。以下查询之一在Postgres中具有最佳性能。在Postgres中使用MAX函数或DESC的最大记录

Select MAX(u.id) from User u; 

Select u.id from User u order by desc limit 1; 
+0

你应该试试你的数据和你的系统。但是,如果你有'user(id)'的索引,那么我希望它们都很快。 –

+0

Max会更快。 – sisanared

+0

检查执行计划 –

回答

0

这是评论的阐述。

如果您有user(id)的索引,那么这两个公式都应该使用该索引。我很肯定他们会有基本相同的执行计划。

如果你没有(b-tree)索引,那么我认为max()版本会更快。我认为它会读取一次数据,并一次提取max()order by将不得不对所有记录进行排序。

有时数据库有一些可能适用的非常具体的优化(例如可能会识别limitorder by的特殊情况的优化)。我认为在这种情况下不适用。

0

这可能取决于你的PostgreSQL版本,但我测试了有代表性的表两种方法(这是你应该做的):

explain analyze select max(id) from versions; 
                      QUERY PLAN                    
-------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Result (cost=0.21..0.21 rows=1 width=0) (actual time=0.034..0.034 rows=1 loops=1) 
    InitPlan 1 (returns $0) 
    -> Limit (cost=0.08..0.21 rows=1 width=4) (actual time=0.031..0.031 rows=1 loops=1) 
      -> Index Only Scan Backward using index_versions_on_id on versions (cost=0.08..98474.35 rows=787172 width=4) (actual time=0.030..0.030 rows=1 loops=1) 
       Index Cond: (id IS NOT NULL) 
       Heap Fetches: 1 
Planning time: 0.143 ms 
Execution time: 0.062 ms 
(8 rows) 

explain analyze select id from versions order by id desc limit 1; 
                     QUERY PLAN                   
------------------------------------------------------------------------------------------------------------------------------------------------------------ 
Limit (cost=0.08..0.21 rows=1 width=4) (actual time=0.025..0.025 rows=1 loops=1) 
    -> Index Only Scan Backward using index_versions_on_id on versions (cost=0.08..98080.76 rows=787172 width=4) (actual time=0.024..0.024 rows=1 loops=1) 
     Heap Fetches: 1 
Planning time: 0.099 ms 
Execution time: 0.044 ms 
(5 rows) 

这是从9.4.5,上唯一索引一张有860,000行的桌子。

这表明按技术顺序稍微快一点,但对我来说,决定你应该使用该方法还不够 - 性能不是一切,我更喜欢max()方法的语义。