Rails 7 + PostgreSQL:在具有 1,2M 行的表中搜索数据超慢。如何加快速度?

问题描述 投票:0回答:1

我有一个数据库表,有接近 100 列 - 25 列是 STRING,其余是 INT/DECIMAL/BOOL。

这是我尝试运行的查询 - 该查询是根据用户必须过滤表中数据的搜索条件生成的

listings
:

SELECT "listings".*
FROM "listings"
WHERE "listings"."source" = 3
  AND "listings"."listing_type" = 4
ORDER BY listings.created_at DESC
LIMIT 100 OFFSET 0

此查询有多种变体,具体取决于用户选择的参数。上面的查询需要 Rails 应用程序超过 4 分钟才能响应(在生产中,它会导致蓝屏显示“出现问题...”,日志中没有错误消息):

Completed 200 OK in 244372ms (Views: 71.4ms | ActiveRecord: 244263.2ms | Allocations: 17464)

我认为可以通过在

WHERE
ORDER BY
子句中的列上添加索引来提高性能,但这没有任何帮助。

我还尝试在 pgAdmin 客户端中运行

EXPLAIN ANALYSE SELECT "listings".* FROM "listings" WHERE "listings"."source" = 3 AND "listings"."listing_type" = 4 ORDER BY listings.created_at DESC LIMIT 100 OFFSET 0
并得到了这个:

"Limit  (cost=0.42..1903.89 rows=100 width=1587) (actual time=64960.075..170237.003 rows=8 loops=1)"
"  ->  Index Scan Backward using index_listings_on_created_at on listings  (cost=0.42..437892.59 rows=23005 width=1587) (actual time=64960.073..170236.988 rows=8 loops=1)"
"        Filter: ((source = 3) AND (listing_type = 4))"
"        Rows Removed by Filter: 1022248"
"Planning Time: 25.418 ms"
"Execution Time: 170237.100 ms"

执行这个

EXPLAIN ANALYSE...
命令,花了2分51秒才得到语句。

此表中的数据工作(加载、搜索、过滤)速度缓慢,导致整个应用程序无法使用。

数据库表

listings

- id (int)
- source (int)
- title (string)
- description (text)
- listing_type (int)
- transaction_type (int)
- region (int)
- uuid (uuid)
- ...other columns...
- created_at (datetime)
- updated_at (datetime)

现有指数:

INDEX NAME           INDEXDEF
listings_pkey      CREATE UNIQUE INDEX listings_pkey ON 
public.listings USING btree (id)          index_listings_on_listing_type CREATE INDEX index_listings_on_listing_type ON public.listings USING btree (listing_type)
index_listings_on_transaction_type  CREATE INDEX index_listings_on_transaction_type ON public.listings USING btree (transaction_type)
index_listings_on_region  CREATE INDEX index_listings_on_region ON public.listings USING btree (region)
index_listings_on_created_at  CREATE INDEX index_listings_on_created_at ON public.listings USING btree (created_at)
index_listings_on_uuid  CREATE INDEX index_listings_on_uuid ON public.listings USING btree (uuid)

我可以采取哪些措施来提高其性能?

注意 - 我使用

will_paginate
进行分页,我了解到 Rails 应用程序中的一个源性能问题是分页 gem 始终运行
SELECT COUNT(*) FROM table
,这对于大表来说是一个问题。

sql ruby-on-rails postgresql indexing
1个回答
0
投票

(source, listing_type, created_at)
上的索引应该是所示查询的神奇解决方案。 不过,我不知道它会如何处理所描述的看不见的变化。

行估计偏差 23005/8 = 2875 的事实当然无助于制定稳健的计划。 你知道为什么会差这么多吗? 如果您仅分别查询源和列表类型(没有 LIMIT 和 ORDER BY),那么这些估计值是否准确?

© www.soinside.com 2019 - 2024. All rights reserved.