我的远程Postgres查询似乎永远挂起

时间:2018-10-12 02:55:57

标签: sql-order-by query-performance postgresql-10 postgres-fdw

我正在从本地客户端的远程Postgres实例上运行以下查询:

select * from matches_tb1 order by match_id desc limit 10;

matches_tb1是一个外部表,并且以match_id作为唯一索引。该查询似乎永远挂起。当我使用explain verbose时,“远程SQL”没有附加ORDER BY。我猜本地服务器没有将命令下推到远程服务器。我该如何解决?

所附为解释结果:

 explain verbose select match_id from matches_tb1 order by match_id desc limit 10;
                                            QUERY PLAN                                             
---------------------------------------------------------------------------------------------------
 Limit  (cost=33972852.96..33972852.98 rows=10 width=8)
   Output: match_id
   ->  Sort  (cost=33972852.96..35261659.79 rows=515522734 width=8)
         Output: match_id
         Sort Key: matches_tb1.match_id DESC
         ->  Foreign Scan on public.matches_tb1  (cost=100.00..22832592.02 rows=515522734 width=8)
               Output: match_id
               Remote SQL: SELECT match_id FROM public.matches_tb1
(8 rows)

1 个答案:

答案 0 :(得分:0)

对于您的问题中的第一个查询:

select * from matches_tb1 order by match_id desc limit 10;

根据EXPLAIN计划,似乎Postgres没有使用match_id B树索引。这导致查询时间非常长,因为数据库必须扫描整个5亿条记录表并进行排序,以查找10条记录。关于为什么 Postgres无法使用索引,问题是select *。当数据库到达索引中每个条目的叶节点时,它只会为match_id找到一个值。但是,由于您正在执行select *,因此数据库将不得不对聚簇索引进行查找以查找所有其他列的值。如果表的相关性较低,那么优化器可能会选择完全放弃索引,而只对表进行完全扫描。

相反,请考虑其他正在快速执行的查询之一:

select match_id from matches_tb1 where match_id > 4164287140
order by match_id desc limit 10

在这种情况下,可以使用match_id 上的索引,因为您只选择了match_id。另外,where子句中的限制甚至可以使索引更加具体。

因此,如果您希望查询快速完成,则解决此问题的方法是不要对select *进行limit。例如,如果您只想说表中的两列col1col2,则可以将这些列添加到索引中以覆盖它们。然后,以下查询也应该很快:

select match_id, col1, col2 from matches_tb1 order by match_id desc limit 10;