我正在从本地客户端的远程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)
答案 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
。例如,如果您只想说表中的两列col1
和col2
,则可以将这些列添加到索引中以覆盖它们。然后,以下查询也应该很快:
select match_id, col1, col2 from matches_tb1 order by match_id desc limit 10;