ORDER BY是否会影响多个WHERE条件?

时间:2018-07-02 19:39:07

标签: postgresql

我正在尝试在名为posts的表上实现分页,并且我将time_createdpost_id列用作页面的分隔符。

有可能在同一时间创建多个帖子,因此在检索下一页时,我需要获取在特定时间创建的所有其余帖子,然后获取在该时间之前创建的帖子。

我担心的是postgres doesn't care about the order of WHERE conditions,并且由于我有2个条件(由OR分隔),因此以下查询可能仅使用第二个条件来满足LIMIT要求。

我的问题是:ORDER BY子句是否保证我提供的(time_created = $1 AND post_id < $2)的第一个条件将首先执行,因为time_created = $1在逻辑上应按降序排列在time_created < $1之前?

SELECT * FROM posts 
WHERE (time_created = $1 AND post_id < $2) OR time_created < $1 
ORDER BY time_created DESC, post_id DESC
limit 50;

1 个答案:

答案 0 :(得分:1)

查询将分三个步骤执行:

  1. 消除WHERE子句中不满足条件的行。
  2. ORDER BY子句中的表达式对其余行进行排序。
  3. 根据LIMIT获取前50行。

因此顺序不影响过滤。

如果您运行EXPLAIN ANALYSE <your query>,将会得到类似以下内容的信息:

                                                                                        QUERY PLAN                                                                                         
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=430.71..430.84 rows=50 width=12) (actual time=1.727..1.730 rows=50 loops=1)
   ->  Sort  (cost=430.71..445.82 rows=6042 width=12) (actual time=1.726..1.727 rows=50 loops=1)
         Sort Key: time_created DESC, post_id DESC
         Sort Method: top-N heapsort  Memory: 27kB
         ->  Seq Scan on posts  (cost=0.00..230.00 rows=6042 width=12) (actual time=0.010..1.329 rows=6027 loops=1)
               Filter: (((time_created = '2018-07-01 00:00:00'::timestamp without time zone) AND (post_id < 1111)) OR (time_created < '2018-07-01 00:00:00'::timestamp without time zone))
               Rows Removed by Filter: 3973
 Planning time: 0.493 ms
 Execution time: 1.759 ms
(9 rows)

可以解释为上述三个步骤。