相关疑难解决方法(0)

复合索引是否也适用于第一个字段的查询?

假设我有一个包含字段A和的表B。我在A+上进行常规查询B,所以我在 上创建了一个复合索引(A,B)A复合索引是否也会对查询进行全面优化?

此外,我在 上创建了一个索引A,但 Postgres 仍然只使用复合索引来查询A。如果前面的答案是肯定的,我想这并不重要,但是为什么它默认选择复合索引,如果单个A索引可用?

postgresql performance index database-design index-tuning

104
推荐指数
1
解决办法
4万
查看次数

为读取性能配置 PostgreSQL

我们的系统写入了大量数据(一种大数据系统)。写入性能足以满足我们的需求,但读取性能真的太慢了​​。

我们所有表的主键(约束)结构都相似:

timestamp(Timestamp) ; index(smallint) ; key(integer).
Run Code Online (Sandbox Code Playgroud)

一个表可以有数百万行,甚至数十亿行,而一个读请求通常是针对特定时间段(时间戳/索引)和标记的。查询返回大约 20 万行是很常见的。目前,我们每秒可以读取大约 15k 行,但我们需要快 10 倍。这是可能的,如果是,如何?

注意: PostgreSQL 是和我们的软件一起打包的,所以不同客户端的硬件是不一样的。

它是一个用于测试的虚拟机。VM 的主机是具有 24.0 GB RAM 的 Windows Server 2008 R2 x64。

服务器规范(虚拟机 VMWare)

Server 2008 R2 x64
2.00 GB of memory
Intel Xeon W3520 @ 2.67GHz (2 cores)
Run Code Online (Sandbox Code Playgroud)

postgresql.conf 优化

shared_buffers = 512MB (default: 32MB)
effective_cache_size = 1024MB (default: 128MB)
checkpoint_segment = 32 (default: 3)
checkpoint_completion_target = 0.9 (default: 0.5)
default_statistics_target = 1000 (default: 100)
work_mem = 100MB (default: 1MB)
maintainance_work_mem = 256MB …
Run Code Online (Sandbox Code Playgroud)

postgresql performance postgresql-9.1 query-performance

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

空间索引可以帮助“范围-排序-限制”查询吗

问这个问题,特别是针对 Postgres,因为它对 R 树/空间索引有很好的支持。

我们有下表,其中包含单词及其频率的树结构(嵌套集模型):

lexikon
-------
_id   integer  PRIMARY KEY
word  text
frequency integer
lset  integer  UNIQUE KEY
rset  integer  UNIQUE KEY
Run Code Online (Sandbox Code Playgroud)

和查询:

SELECT word
FROM lexikon
WHERE lset BETWEEN @Low AND @High
ORDER BY frequency DESC
LIMIT @N
Run Code Online (Sandbox Code Playgroud)

我认为覆盖索引(lset, frequency, word)会很有用,但我觉得如果范围内的lset值太多,它可能表现不佳(@High, @Low)

(frequency DESC)有时,当使用该索引的搜索早期产生@N与范围条件匹配的行时,一个简单的索引也可能就足够了。

但似乎性能在很大程度上取决于参数值。

有没有办法让它快速执行,不管范围(@Low, @High)是宽还是窄,也不管高频词是否幸运地在(窄)选择的范围内?

R-tree/空间索引有帮助吗?

添加索引,重写查询,重新设计表,没有限制。

postgresql performance index database-design query-performance

28
推荐指数
2
解决办法
4312
查看次数

递归 CTE 以找到独特的 slug

我有一个文章表,我希望 slug 是独一无二的。

CREATE TABLE article (
   title char(50) NOT NULL,
   slug  char(50) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

当用户输入标题时,例如News on Apple,我想检查数据库以查看是否存在相应的 slug,例如news-on-apple。如果是这样,我将给一个数值添加后缀,直到找到一个唯一的值,例如news-on-apple-1. 可以通过递归 CTE 查询而不是在我的 ORM 中进行递归来实现。是否有一个很好的大概数字,我应该停止递归和出错。我可以想象人们使用相同的标题 1000 次,这将导致 1000 次查询只是为了创建 1 篇文章。

我对递归 CTE 的理解可能是不正确的,并且没有更好的方法来找到唯一的 slug。请提出任何替代方案。

postgresql database-design cte recursive

7
推荐指数
1
解决办法
1715
查看次数

为什么添加 LIMIT 200 会导致查询变慢?

我正在尝试调试 PostgreSQL 9.1.13 数据库上的慢查询,我有点不知所措。ORM 框架生成的确切查询是:

SELECT "core_product"."sales_price", "core_product"."recommended_price", "core_productgroup"."name", "core_product"."number", "core_product"."name", "core_product"."description", "core_product"."cost_price", "core_product"."bar_code", "core_product"."accessible"
FROM "core_product" INNER JOIN "core_productgroup" ON ( "core_product"."product_group_id" = "core_productgroup"."id" )
WHERE "core_productgroup"."company_id" = 1056
ORDER BY "core_product"."id" ASC
LIMIT 200;
Run Code Online (Sandbox Code Playgroud)

此查询需要 28 秒才能返回 200 行,这对于我们的用例来说太慢了。

首次尝试了解性能瓶颈可能在哪里。我首先尝试删除LIMIT 200预期它会更慢。但是没有LIMIT 200查询只需要 2 秒就返回大约 293000 行。

如何更快地返回所有 293000 个匹配行而不是仅返回前 200 行?

我尝试使用EXPLAIN查看两个查询的查询计划有何不同。事实证明,这两个几乎相同的查询具有完全不同的查询计划。与LIMIT

                                                   QUERY PLAN                                                   
----------------------------------------------------------------------------------------------------------------
 Limit  (cost=10.69..52229.70 rows=200 width=76)
   ->  Nested Loop  (cost=10.69..17054740.55 rows=65320 width=76)
         Join Filter: (core_product.product_group_id = core_productgroup.id) …
Run Code Online (Sandbox Code Playgroud)

postgresql

7
推荐指数
2
解决办法
4614
查看次数

按引用表中的相关行数排序

假设有两个表:

用户

id [pk] |   name
--------+---------
      1 | Alice
      2 | Bob
      3 | Charlie
      4 | Dan
Run Code Online (Sandbox Code Playgroud)

电子邮件

 id | user_id | email 
----+---------+-------
  1 |       1 | a.1
  2 |       1 | a.2
  3 |       2 | a.3
  4 |       2 | b.1
  5 |       2 | a.4
  6 |       2 | a.5
  7 |       3 | b.2
  8 |       3 | a.6
Run Code Online (Sandbox Code Playgroud)

随着查询我要检索:

  • 用户的 ID 和名称
  • 用户的电子邮件数
  • 用户的电子邮件及其 ID

我希望输出按电子邮件数量降序排列并过滤,仅包括以“a”开头的电子邮件。没有电子邮件的用户也应包括在内 - 将他们的电子邮件计数视为0。 …

postgresql join window-functions postgresql-9.3

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

如何强制 PostgreSQL 中 WHERE 子句的顺序?

我在 Postgres 表中有 6 列:

A1 character varying(5)[]
A2 character varying(5)[]
A3 int REFERENCES ... -- FK 
B1 character varying(5)[]
B2 character varying(5)[]
B3 int REFERENCES ... -- FK 
Run Code Online (Sandbox Code Playgroud)

我需要一个SELECT匹配的第一行是获胜者(限制为 1)并匹配 A 组和 B 组。

我知道 Postgres 不关心WHERE子句的顺序,我必须准备一个ORDER子句或找到不同的方法。

我想准备匹配优先级的查找,我的WHERE子句重要性如下:

highest priority: (A1 and B1) OR
.                 (A1 and B2 OR A2 and B1) OR
.                 (A1 and B3 OR A3 and B1) OR
.                 (A2 and B3 OR A3 and B2) OR …
Run Code Online (Sandbox Code Playgroud)

postgresql order-by

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