database - Postgres。查询有时会很长。

标签 database postgresql

我需要帮助或任何提示。我有 Postgres DB 9.4,有时处理一个查询非常慢。

SELECT COUNT(*) FROM "table_a" INNER JOIN "table_b" ON "table_b"."id" = "table_a"."table_b_id" AND "table_b"."deleted_at" IS NULL WHERE "table_a"."deleted_at" IS NULL AND "table_b"."company_id" = ? AND "table_a"."company_id" = ?

这个的查询计划 -

Aggregate (cost=308160.70..308160.71 rows=1 width=0)
             -> Hash Join (cost=284954.16..308160.65 rows=20 width=0)
                                    Hash Cond: ?
    -> Bitmap Heap Scan on table_a (cost=276092.39..299260.96 rows=6035 width=4)
                                    Recheck Cond: ?
                                                Filter: ?
-> Bitmap Index Scan on index_table_a_on_created_at_and_company_id (cost=0.00..276090.89 rows=6751 width=0)
                                         Index Cond: ?
            -> Hash (cost=8821.52..8821.52 rows=3220 width=4)
        -> Bitmap Heap Scan on table_b (cost=106.04..8821.52 rows=3220 width=4)
                                Recheck Cond: ?
                                                Filter: ?
    -> Bitmap Index Scan on index_ table_b_on_company_id (cost=0.00..105.23 rows=3308 width=0)
                                        Index Cond: ? 

但通常,这是查询执行得足够快(大约 69.7 毫秒)。我不明白为什么有时会发生这种情况。我在这段时间的性能日志中看到,我的 RDS 实例消耗了大量内存并且计算此查询达到每秒 100 次左右。伙计们,请帮忙,我该去哪里解决这个问题。

最佳答案

我不确定这是否能解决您的问题:)

  • 当此查询返回非常快的结果时,它会从缓存中返回结果并且不会再次执行查询并且当时不会准备结果。

  • 首先,您必须检查是否有太多查询正在对这些表执行,尤其是inserts/updated/deletes。这种类型的查询会导致锁定,select 必须等到锁定被释放。

  • 查询可能会很慢,因为 table_atable_b 之间的 joinwhere 子句的比较成本太大.

  • 您可以通过申请 indexes 来降低成本列 "table_b"."id", "table_a"."table_b_id", "table_a"."deleted_at", "table_b"."company_id", AND "table_a"."company_id"

  • 您可以创建一个 view以降低成本。 View 正在返回缓存信息。

  • 最后一件事是您还可以通过使用临时表来降低成本。我在下面给出了一个例子。

查询:

CREATE TEMPORARY TABLE table_a_temp as 
SELECT "table_a"."table_b_id" FROM "table_a" 
WHERE "table_a"."deleted_at" IS NULL AND "table_a"."company_id" = ? ;

CREATE TEMPORARY TABLE table_b_temp as 
SELECT "table_b"."id" FROM "table_a" 
WHERE"table_b"."deleted_at" IS NULL AND "table_b"."company_id" = ?;

SELECT COUNT(*) FROM "table_a_temp" INNER JOIN "table_b_temp" 
ON "table_b_temp"."id" = "table_a_temp"."table_b_id" ;

关于database - Postgres。查询有时会很长。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34023265/

相关文章:

java - 使用 BlueMix 尝试将 JSON 数据插入 Cloudant 数据库,而无需在 Java 中对文件格式进行硬编码

django - 刷新单个应用程序 django 1.9

java - Realm 迁移重复值

ruby-on-rails - 在 ActiveRecord 模型上使用建立连接时出现 AdapterNotSpecified

sql - 如何选择列值为空的行?

c# - 通知客户更新的最佳方式?

postgresql - pg_similarity 是否仍然保持?

java - 将 xml 模式导入 postgres 以自动创建一个表,然后用 xml 文件填充它?

ruby-on-rails - ActiveRecord 列无法自动转换为数字类型

sql - PostgreSQL 使用另一列的值更新 JSONB 列