2

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

select * from matches_tb1 order by match_id desc limit 10;

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

附上解释结果:

 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)
4

1 回答 1

0

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

select * from matches_tb1 order by match_id desc limit 10;

根据EXPLAINPostgres 不使用match_idB-tree 索引的计划出现。这导致查询很长,因为数据库必须扫描整个 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 可以使用索引 on,因为您只选择match_id. 此外,where子句中的限制更有助于使索引更具体。

因此,如果您希望查询快速完成,那么解决您的问题的方法就是不select *使用。limit例如,如果您只想说两列col1并且col2来自您的表,那么您可以将这些列添加到索引中以覆盖它们。那么,下面的查询也应该很快:

select match_id, col1, col2 from matches_tb1 order by match_id desc limit 10;
于 2018-10-12T03:00:09.937 回答