相关疑难解决方法(0)

Postgres JOIN 条件与 WHERE 条件

Postgres 新手在这里。

我想知道这个查询是否经过优化?我试图仅加入 100% 必要的值,并将所有动态条件留在 WHERE 子句中。见下文。

SELECT *
    FROM
      myapp_employees
    JOIN myapp_users ON
      myapp_users.user_id=myapp_employees.user_id
    JOIN myapp_contacts_assoc ON
      myapp_contacts_assoc.user_id=myapp_users.user_id
    JOIN myapp_contacts ON
      myapp_contacts.contact_id=myapp_contacts_assoc.contact_id
    WHERE
      myapp_contacts.value='test@gmail.com' AND
      myapp_contacts.type=(1)::INT2 AND
      myapp_contacts.is_primary=(1)::INT2 AND
      myapp_contacts.expired_at IS NULL AND
      myapp_employees.status=(1)::INT2 AND
      myapp_users.status=(1)::INT2
    LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

注意:对于上下文,此过程正在检查用户是否也是员工(提升的权限/不同的用户类型)。

无论如何,这是正确的方法吗?例如,JOIN ON 是否应该包含更多语句,例如检查 expired_at IS NULL?为什么或为什么这没有意义?

postgresql join optimization

13
推荐指数
1
解决办法
2万
查看次数

在单个 SELECT 语句中返回多个范围的计数

我有一个 Postgres 数据库表foo,其中有一个score范围为 0 - 10的列。我想要一个查询来返回分数总数、0 到 3 之间的分数数、4 之间的分数数和 6,以及 7 到 10 之间的分数。类似于以下内容:

SELECT
  COUNT(*) as total,
  COUNT(
    SELECT * from foo where score between 0 and 3;
  ) as low,
  COUNT(
    SELECT * from foo where score between 4 and 6;
  ) as mid,
  COUNT(
    SELECT * from foo where score between 7 and 10;
  ) as high
FROM foo;
Run Code Online (Sandbox Code Playgroud)

我试过这个,但SELECTCOUNT语句中出现错误。任何想法我怎么能做到这一点?我确定 Postgres 中有一个超级简单的方法。我只是想不出 Google 的正确术语。

postgresql aggregate aggregate-filter

12
推荐指数
2
解决办法
4万
查看次数

小表会导致性能极度下降,已通过强制 VACUUM 修复。为什么?

我使用 PostgreSQL 9.6。

我有一个连接 17 个表的查询,其中 9 个有几百万行。查询运行良好,但本周其性能迅速下降。EXPLAIN 的输出没有帮助(所有扫描都是索引扫描,除了非常小的表),我不得不尝试从查询中删除表以隔离导致降级的表。

事实证明,一个包含 40 行的不起眼的表破坏了查询:800 ms 没有该表,而有 30 s。我在桌子上运行了 VACUUM FULL,它运行了大约一秒钟,现在性能恢复正常。

我的问题:

  1. 什么可以解释 <10kb 的表像这样破坏性能?
  2. 以后如何避免同样的问题?

在调试过程中,我对另一台服务器进行了基本备份,因此我有两个文件系统级别的数据库副本,其中一个我没有运行 VACUUM FULL。当我使用 pgAdmin 登录到 unvacuumed 副本时,我收到以下消息:

表“public.clients”上的估计行数与实际行数显着不同。您应该在此表上运行 VACUUM ANALYZE。

unvacuumed 表有 40 行计数和 0 估计。以下是屏幕截图中的其余统计数据。

pgAdmin 统计信息

postgresql performance statistics autovacuum postgresql-9.6 query-performance

6
推荐指数
1
解决办法
857
查看次数

使用小 LIMIT 优化查询,对一列进行谓词并按另一列排序

我使用的是 Postgres 9.3.4,我有 4 个查询,它们的输入非常相似,但响应时间却大不相同:

查询#1

EXPLAIN ANALYZE SELECT posts.* FROM posts
WHERE posts.source_id IN (19082, 19075, 20705, 18328, 19110, 24965, 18329, 27600, 17804, 20717, 27598, 27599)
AND posts.deleted_at IS NULL
ORDER BY external_created_at desc
LIMIT 100 OFFSET 0;
                                                                                 QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..585.44 rows=100 width=1041) (actual time=326092.852..507360.199 rows=100 loops=1)
   ->  Index Scan using index_posts_on_external_created_at on posts  (cost=0.43..14871916.35 rows=2542166 width=1041) (actual time=326092.301..507359.524 rows=100 loops=1)
         Filter: (source_id = ANY ('{19082,19075,20705,18328,19110,24965,18329,27600,17804,20717,27598,27599}'::integer[]))
         Rows Removed by Filter: 6913925
 Total runtime: 507361.944 ms
Run Code Online (Sandbox Code Playgroud)

查询#2

EXPLAIN …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index optimization postgresql-9.3 postgresql-performance

5
推荐指数
1
解决办法
895
查看次数

隐式连接与 Postgres 中的显式连接一样有效吗?

通常这样写很方便:

SELECT * 
FROM t1   # ... +many more tables
INNER JOIN t2 ON (t1.id = t2.col)
INNER JOIN t3 ON (t1.id = t3.col)
INNER JOIN t4 ON (t1.id = t4.col)
...
Run Code Online (Sandbox Code Playgroud)

作为带条件的交叉连接:

SELECT * 
FROM t1, t2, t3, t4   # ... +many more tables
WHERE
       t1.id = t2.col
   AND t1.id = t3.col
   AND t1.id = t4.col
   # +include matches on columns of other tables
Run Code Online (Sandbox Code Playgroud)

但是,交叉连接的简单实现将比内部连接具有更高的时间复杂度。Postgres 是否将第二个查询优化为与第一个查询具有相同时间复杂度的查询?

postgresql join execution-plan

2
推荐指数
1
解决办法
2444
查看次数