Postgresql 为什么在查询中小于(<;)比大于(>;)具有更好的性能?

Postgresql 为什么在查询中小于(<;)比大于(>;)具有更好的性能?,postgresql,Postgresql,在下面的查询中,您将看到使用运算符的查询需要0.474s。这是一个巨大的差异。发生了什么事 postgresql> SHOW server_version; +------------------+ | server_version | |------------------| | 9.4.17 | +------------------+ SHOW Time: 0.006s postgresql> \d msg +------------------+--

在下面的查询中,您将看到使用<运算符的查询只需要0.007s,而使用>运算符的查询需要0.474s。这是一个巨大的差异。发生了什么事

postgresql> SHOW server_version;
+------------------+
| server_version   |
|------------------|
| 9.4.17           |
+------------------+
SHOW
Time: 0.006s

postgresql> \d msg
+------------------+-----------------------------+-------------------------------------------------------------+
| Column           | Type                        | Modifiers                                                   |
|------------------+-----------------------------+-------------------------------------------------------------|
| id               | bigint                      |  not null default nextval('msg_id_seq'::regclass) |
| content          | text                        |  default ''::text                                           |
... ...
| created_at       | timestamp without time zone |  default timezone('UTC'::text, now())                       |
+------------------+-----------------------------+-------------------------------------------------------------+
Indexes:
    "msg_pkey" PRIMARY KEY, btree (id)
    "ix_msg_created_at" btree (created_at)

Time: 0.013s

postgresql> SELECT id FROM msg WHERE created_at < '2020-08-27' ORDER BY id desc LIMIT 1;
+--------+
| id     |
|--------|
| 973604 |
+--------+
SELECT 1
Time: 0.007s

postgresql> SELECT id FROM msg WHERE created_at > '2020-08-27' ORDER BY id LIMIT 1;
+--------+
| id     |
|--------|
| 973605 |
+--------+
SELECT 1
Time: 0.474s

postgresql> SELECT count(*) FROM msg WHERE created_at < '2020-08-27';
+---------+
| count   |
|---------|
| 967498  |
+---------+
SELECT 1
Time: 0.509s

postgresql> SELECT count(*) FROM msg WHERE created_at > '2020-08-27';
+---------+
| count   |
|---------|
| 1089    |
+---------+
SELECT 1
Time: 0.007s

postgresql> EXPLAIN ANALYZE SELECT id FROM msg WHERE created_at < '2020-08-27' ORDER BY id desc LIMIT 1;
+------------------------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN                                                                                                                                                 |
|------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Limit  (cost=0.43..0.53 rows=1 width=8) (actual time=0.770..0.770 rows=1 loops=1)                                                                          |
|   ->  Index Scan Backward using msg_pkey on msg  (cost=0.43..114629.92 rows=1092141 width=8) (actual time=0.770..0.770 rows=1 loops=1) |
|         Filter: (created_at < '2020-08-27 00:00:00'::timestamp without time zone)                                                                          |
|         Rows Removed by Filter: 1103                                                                                                                       |
| Planning time: 0.110 ms                                                                                                                                    |
| Execution time: 0.782 ms                                                                                                                                   |
+------------------------------------------------------------------------------------------------------------------------------------------------------------+
EXPLAIN
Time: 0.008s

postgresql> EXPLAIN ANALYZE SELECT id FROM msg WHERE created_at > '2020-08-27' ORDER BY id LIMIT 1;
+----------------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN                                                                                                                                         |
|----------------------------------------------------------------------------------------------------------------------------------------------------|
| Limit  (cost=0.43..44.58 rows=1 width=8) (actual time=481.168..481.169 rows=1 loops=1)                                                             |
|   ->  Index Scan using msg_pkey on msg  (cost=0.43..114629.92 rows=2596 width=8) (actual time=481.166..481.166 rows=1 loops=1) |
|         Filter: (created_at > '2020-08-27 00:00:00'::timestamp without time zone)                                                                  |
|         Rows Removed by Filter: 967498                                                                                                             |
| Planning time: 0.124 ms                                                                                                                            |
| Execution time: 481.184 ms                                                                                                                         |
+----------------------------------------------------------------------------------------------------------------------------------------------------+
EXPLAIN
Time: 0.489s

postgresql>显示服务器版本;
+------------------+
|服务器版本|
|------------------|
| 9.4.17           |
+------------------+
显示
时间:0.006s
postgresql>\d msg
+------------------+-----------------------------+-------------------------------------------------------------+
|列|类型|修饰符|
|------------------+-----------------------------+-------------------------------------------------------------|
|id | bigint |非空默认nextval('msg_id_seq'::regclass)|
|内容|文本|默认“”::文本|
... ...
|在|无时区的时间戳|默认时区('UTC'::text,now())创建|u|
+------------------+-----------------------------+-------------------------------------------------------------+
索引:
“msg_pkey”主键,btree(id)
“ix_msg_created_at”btree(created_at)
时间:0.013s
postgresql>从msg中选择id,创建位置为“2020-08-27”,按id描述限制1排序;
+--------+
|身份证|
|--------|
| 973604 |
+--------+
选择1
时间:0.007s
postgresql>在“2020-08-27”中创建的消息中选择id,按id限制1排序;
+--------+
|身份证|
|--------|
| 973605 |
+--------+
选择1
时间:0.474s
postgresql>从msg中选择count(*),创建位置为<'2020-08-27';
+---------+
|计数|
|---------|
| 967498  |
+---------+
选择1
时间:0.509秒
postgresql>从“2020-08-27”中创建的消息中选择计数(*);
+---------+
|计数|
|---------|
| 1089    |
+---------+
选择1
时间:0.007s
postgresql>解释分析从msg中选择id,其中创建于<'2020-08-27'订单,按id描述限制1;
+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|查询计划|
|------------------------------------------------------------------------------------------------------------------------------------------------------------|
|限制(成本=0.43..0.53行=1宽度=8)(实际时间=0.770..0.770行=1圈=1)|
|->使用msg上的msg_pkey反向索引扫描(成本=0.43..114629.92行=1092141宽度=8)(实际时间=0.770..0.770行=1循环=1)|
|过滤器:(创建于<'2020-08-27 00:00:00'::不带时区的时间戳)|
|被筛选器删除的行:1103|
|计划时间:0.110毫秒|
|执行时间:0.782毫秒|
+------------------------------------------------------------------------------------------------------------------------------------------------------------+
说明
时间:0.008s
postgresql>解释分析从msg中选择id,在“2020-08-27”中创建,按id限制1排序;
+----------------------------------------------------------------------------------------------------------------------------------------------------+
|查询计划|
|----------------------------------------------------------------------------------------------------------------------------------------------------|
|限制(成本=0.43..44.58行=1宽度=8)(实际时间=481.168..481.169行=1圈=1)|
|->在msg上使用msg_pkey进行索引扫描(成本=0.43..114629.92行=2596宽度=8)(实际时间=481.166..481.166行=1循环=1)|
|过滤器:(创建于>'2020-08-27 00:00:00'::不带时区的时间戳)|
|被筛选器删除的行:967498|
|计划时间:0.124毫秒|
|执行时间:481.184毫秒|
+----------------------------------------------------------------------------------------------------------------------------------------------------+
说明
时间:0.489秒
更新以添加行数(2020-09-01):

  • 2020-08-27之后创建的行数为1089
  • 2020-08-27之前创建的行数为967498
更新以添加查询计划(2020-09-01)

  • 这两个查询似乎都在使用index
    msg\u pkey
    而不是
    ix\u msg\u created\u at
    。过滤器删除的
    行的差异应该可以解释性能差异

正如
EXPLAIN
的输出所示,两个查询似乎都扫描索引
msg\u pkey
,而不是
ix\u msg\u created\u at
。正如过滤器删除的
行所示,使用
操作符的查询将进行扫描