相关疑难解决方法(0)

多列索引和性能

我有一个带有多列索引的表,我怀疑索引的正确排序以获得最大查询性能。

场景:

  • PostgreSQL 8.4,大约有一百万行的表

  • c1列中的值可以有大约100 个不同的值。我们可以假设这些值是均匀分布的,因此每个可能的值大约有 10000 行。

  • c2可以有1000 个不同的值。对于每个可能的值,我们有 1000 行。

搜索数据时,条件始终包含这两列的值,因此该表具有组合 c1 和 c2 的多列索引。如果您的查询仅使用一列进行过滤,我已经阅读了正确排序多列索引中的列的重要性。在我们的场景中,情况并非如此。

我的问题是这个:

鉴于其中一个过滤器选择的数据集要小得多,如果第一个索引是最具选择性的索引(允许更小的数据集),我是否可以提高性能?在我看到参考文章中的图形之前,我从未考虑过这个问题:

在此处输入图片说明

图片取自有关多列索引的参考文章。

查询使用两列中的值进行过滤。我没有仅使用一列进行过滤的查询。他们都是:WHERE c1=@ParameterA AND c2=@ParameterB。还有这样的条件:WHERE c1 = "abc" AND c2 LIKE "ab%"

postgresql index index-tuning

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

在 Postgres 列上创建唯一约束是否不需要对其进行索引?

在 Postgres 列上创建唯一约束是否不需要对其进行索引?

我希望自动需要一个索引来有效地维护约束。

postgresql index database-design unique-constraint

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

CLUSTER 对性能的影响

我正在尝试优化我的 Postgres 9.2 数据库以加快具有日期限制的查询。

我有一个timestamp专栏,但主要是我要求某一天,所以我创建了一个timestamp用于date解析的索引:

CREATE INDEX foo_my_timestamp_idx
ON foo
USING btree
((my_timestamp::date) DESC);
Run Code Online (Sandbox Code Playgroud)

现在,为了提高性能,我CLUSTER foo使用上面的索引表:

CLUSTER foo USING foo_my_timestamp_idx;
Run Code Online (Sandbox Code Playgroud)

根据手册上SQL-CLUSTER,表

根据索引信息进行物理重新排序

我想知道是否会对使用表 PK 的其他查询的性能产生影响(比如说id_foo)。有什么缺点吗?

postgresql performance storage index-tuning postgresql-9.2 postgresql-performance

10
推荐指数
1
解决办法
3483
查看次数

优化一系列时间戳的查询(一列)

我正在通过 Heroku 使用 Postgres 9.3。

我有一个表,“交通”,有 100 万条记录,每天都有很多插入和更新。我需要在不同的时间范围内跨该表执行 SUM 运算,这些调用最多可能需要 40 秒,我很想听听有关如何改进它的建议。

我在这张桌子上有以下索引:

CREATE INDEX idx_traffic_partner_only ON traffic (dt_created) WHERE campaign_id IS NULL AND uuid_self <> uuid_partner;
Run Code Online (Sandbox Code Playgroud)

这是一个示例 SELECT 语句:

SELECT SUM("clicks") AS clicks, SUM("impressions") AS impressions
FROM "traffic"
WHERE "uuid_self" != "uuid_partner"
AND "campaign_id" is NULL
AND "dt_created" >= 'Sun, 29 Mar 2015 00:00:00 +0000'
AND "dt_created" <= 'Mon, 27 Apr 2015 23:59:59 +0000' 
Run Code Online (Sandbox Code Playgroud)

这是解释分析:

Aggregate  (cost=21625.91..21625.92 rows=1 width=16) (actual time=41804.754..41804.754 rows=1 loops=1)
  ->  Index Scan using idx_traffic_partner_only on …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index optimization postgresql-9.3 postgresql-performance

9
推荐指数
1
解决办法
5849
查看次数

tsrange 上的 2 个 B 树索引或 1 个 GiST 索引——哪个性能更好?

我有一个表,它使用列存储预订数据starts_atends_at每当我查询表以查找重叠预订时,我都可以选择使用以下查询之一:

SELECT * FROM reservations
WHERE starts_at < '2014-01-03 00:00:00'
AND   ends_at   >='2014-01-01 00:00:00';
Run Code Online (Sandbox Code Playgroud)

或者

SELECT * FROM reservations
WHERE tsrange(starts_at, ends_at) && ('2014-01-01 00:00:00', '2014-01-03 00:00:00')
Run Code Online (Sandbox Code Playgroud)

我在starts_atends_at列上有常规的 B 树索引,因此第一个查询总是使用它们。但是,除非我在 tsrange 上定义功能性 GiST 索引,否则第二个查询会执行完整扫描。

create index tsrange_idx on reservations using gist(tsrange(starts_at, ends_at)); 
Run Code Online (Sandbox Code Playgroud)

我的问题是,随着表的增长,哪个索引会更快?查看查询执行计划,答案可能很明显,但我不精通读取EXPLAIN ANALYZE输出。

postgresql index index-tuning postgresql-9.2 gist-index

8
推荐指数
1
解决办法
3802
查看次数

多对多关系中不同 ID 的最快查询

我在 PostgreSQL 9.4 中有这个表:

CREATE TABLE user_operations( 
    id SERIAL PRIMARY KEY, 
    operation_id integer, 
    user_id integer )
Run Code Online (Sandbox Code Playgroud)

该表由~1000-2000不同的操作组成,每个操作对应于所有用户80000-120000集合S的某个子集(每个子集由大约元素组成):

S = {1, 2, 3, ... , 122655}
Run Code Online (Sandbox Code Playgroud)

参数:

work_mem = 128MB
table_size = 880MB
Run Code Online (Sandbox Code Playgroud)

我也有一个关于operation_id.

问题:user_id对于operation_id集合的重要部分(20%-60%)查询所有不同的最佳计划是什么,例如:

SELECT DISTINCT user_id FROM user_operation WHERE operation_id < 500
Run Code Online (Sandbox Code Playgroud)

可以在表上创建更多索引。目前,查询的计划是:

HashAggregate  (cost=196173.56..196347.14 rows=17358 width=4) (actual time=1227.408..1359.947 rows=598336 loops=1)
  ->  Bitmap Heap Scan on user_operation  (cost=46392.24..189978.17 rows=2478155 width=4) (actual time=233.163..611.182 rows=2518122 loops=1)
        Recheck Cond: …
Run Code Online (Sandbox Code Playgroud)

postgresql performance count distinct postgresql-performance

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

查找与目标日期范围重叠的所有日期范围

假设我希望在员工休假 ( FromDate, ToDate)时进行存储,然后我希望找到在两个给定日期 ( QFromDate, QToDate)之间休假的所有员工。

现在假设我有很多这样的记录(超过服务器 RAM 的容量)并且需要经常执行此查询。

现在假设我还有sick_leave表格、shift_pattern表格、pay_rate表格等——所有这些都具有FromDateToDate需要根据重叠日期将它们连接起来。

我应该如何存储日期范围以及如何编写查询以快速运行?

(RDBMS 的选择不是固定的,但能够在任何“标准”RDBMS 上运行是有价值的,除非这样做会产生很大的不利影响。)

我已经发布了一些我考虑过的答案,但不喜欢!然而,他们可能会帮助其他人。

performance oracle database-design sql-server query-performance

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

按顺序插入和聚类效果一样吗?

我有一个表,其中包含一些基于其他表的预先计算的数据。(考虑到我必须处理的数据大小,动态计算的计算成本太高。)随着源数据的添加,我将逐步生成。(UPDATE在正常使用中我永远不需要它;部分可能会被删除和重新生成。)该表将相当大。它目前大约有 5000 万行,并且每年都会增长。

对该表的大多数查询都将通过外键 ID 列进行过滤。因此,如果该 ID 的所有行都分组到相同的页面中,它们的性能会更好。我可以通过创建索引和CLUSTER定期调用来保证磁盘上的这种排序,但这显然不太理想,因为它需要某种计划任务,根据使用情况和其他计划任务进行协调等。

但是,由于我以与我想要使用的外键相关的块的形式生成这些数据CLUSTER,因此我可以轻松地ORDER BYINSERT命令中添加一个子句:

INSERT INTO big_table (source_table1_id,a,b,c)
SELECT
   source_table1_id,
   5 /* some formula */,
   /* ... */
FROM source_table1
JOIN source_table2 ON ...
...
WHERE ... /* some condition indicating what needs to be generated */
ORDER BY source_table1_id
Run Code Online (Sandbox Code Playgroud)

这是否会影响磁盘存储顺序,将行分组为接近最小页数?如果确实如此,是否还有其他进程可能会在以后弄乱磁盘顺序?

我目前正在使用 PostgreSQL 9.3,但我想了解更新的版本以及升级。

postgresql performance

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

重叠范围的最大 sum()

基本上我的问题是:如何在 PostgreSQL 9.3(或 9.4)中进行涉及重叠范围的聚合操作?我手头的具体问题是,给定一个范围,我想找到适用重叠范围的最大 sum()。一个简单的例子:

create table event (
  event_id int primary key,
  event_type_id int not null,
  period tstzrange not null,
  quantity int not null
);

insert into event (event_id, event_type_id, period, quantity) values
(1, 1,'[2016-01-06 09:00:00+00,2016-01-08 17:00:00+00]',1),
(2, 1,'[2016-01-07 09:00:00+00,2016-01-07 11:00:00+00]',1),
(3, 1,'[2016-01-07 13:00:00+00,2016-01-07 17:00:00+00]',1),
(4, 2,'[2016-01-07 12:00:00+00,2016-01-07 17:00:00+00]',1);
Run Code Online (Sandbox Code Playgroud)

给定具有以下子句的查询:

select ... 
where event_type_id = 1
and period && '[2016-01-07 00:00:00+00,2016-01-07 23:59:00+00]'::tstzrange 
group by event_type_id
Run Code Online (Sandbox Code Playgroud)

期望的结果是:3,即在给定时间戳范围内sum(quantity)相同范围event_type_id重叠的最大值。

postgresql window-functions postgresql-9.3 range-types

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

Postgres 中索引列的查询速度极慢

我对索引列的查询速度非常慢。鉴于查询

SELECT * 
FROM orders 
WHERE shop_id = 3828 
ORDER BY updated_at desc 
LIMIT 1
Run Code Online (Sandbox Code Playgroud)

explain analyze 回来:

    QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..594.45 rows=1 width=175) (actual time=202106.830..202106.831 rows=1 loops=1)
   ->  Index Scan Backward using index_orders_on_updated_at on orders  (cost=0.43..267901.54 rows=451 width=175) (actual time=202106.827..202106.827 rows=1 loops=1)
         Filter: (shop_id = 3828)
         Rows Removed by Filter: 1604818
 Planning time: 98.579 ms
 Execution time: 202127.514 ms
(6 rows)
Run Code Online (Sandbox Code Playgroud)

表说明为:

                                         Table "public.orders"
       Column       |            Type             |                           Modifiers
--------------------+-----------------------------+---------------------------------------------------------------
 id                 | integer                     | not null default nextval('orders_id_seq'::regclass) …
Run Code Online (Sandbox Code Playgroud)

postgresql performance order-by index-tuning amazon-rds

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