首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >邮政分拣

邮政分拣
EN

Stack Overflow用户
提问于 2016-09-09 07:18:06
回答 2查看 107关注 0票数 1

有一个具有这种结构的表:

代码语言:javascript
运行
复制
    Table "public.all_emails"
│ Column | Type | Modifiers
│ ----------- + -------- + -----------
│ email | text |
│ frequency | bigint |
│Indexes:
│ "all_emails_email_idx" UNIQUE, btree (email)

我希望通过对这些记录进行更多的操作,将所有记录从这个表移到另一个数据库中。为了加快速度,我编写了多进程应用程序,该应用程序需要几次特定的表。为了知道以下哪个过程开始,我对表进行了如下排序:

代码语言:javascript
运行
复制
Select email from all_emails order by email limit # {PULL_SIZE} offset # {offset}

由于表中有大量的记录,这个操作非常昂贵,而且不是最优的。我怎样才能让它变得更好?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-09 07:56:38

为此,您可以对您的表进行CLUSTER

代码语言:javascript
运行
复制
CLUSTER all_emails USING all_emails_email_idx;
ANALYZE all_emails;

根据指定的索引对表中的行进行物理重新排序。因此,电子邮件地址是根据电子邮件地址排序的,然后查询--就像处理任何其他查询一样--将在有限数量的磁盘页面上找到请求子集中的所有行,因此I/O减少,以及任何排序(因为查询计划器识别表聚集在特定索引上)。ANALYZE命令在集群之后更新表统计信息,以帮助查询规划者做出最佳选择。

这实际上只适用于只读或不经常更新或插入新行的表,因为群集不被维护:这是一个一次性的过程。集群也是一个相当“昂贵”的过程,因为整个表是重写的,并且需要一个排他的表锁。您可以使用缩写形式CLUSTER all_emails的相同索引定期重新对表进行重新聚类。

票数 1
EN

Stack Overflow用户

发布于 2016-09-09 07:56:45

没有什么比读取整个表的单次顺序扫描速度更快的了,至少在PostgreSQL 9.6之前是这样,在此之前,并行顺序扫描将被引入。

将表拆分为ctid (表中元组的物理位置)是很有诱惑力的,但是PostgreSQL并没有为不同于=的运营商优化ctid的访问

代码语言:javascript
运行
复制
test=> EXPLAIN SELECT * FROM large WHERE ctid BETWEEN '(390, 0)' AND '(400,0)';
┌───────────────────────────────────────────────────────────────────┐
│                            QUERY PLAN                             │
├───────────────────────────────────────────────────────────────────┤
│ Seq Scan on large  (cost=0.00..1943.00 rows=500 width=8)          │
│   Filter: ((ctid >= '(390,0)'::tid) AND (ctid <= '(400,0)'::tid)) │
└───────────────────────────────────────────────────────────────────┘
(2 rows)

插入的情况也是如此:如果不能显示数字,我非常肯定,将一个进程INSERTing或COPYing放到一个表中不会比将数据加载到同一个表中的几个进程慢。

由于瓶颈似乎是处理原点的SELECT和目的地的INSERT之间的行,我建议如下:

  1. 有一个执行单个SELECT * FROM all_emails的线程。
  2. 创建多个可以并行执行昂贵处理的线程。
  3. 第一个线程以循环方式将结果行分发给并行工作人员。
  4. 还有一个线程收集并行工作人员的结果,并将它们组合到它执行的COPY tablename FROM STDIN语句的输入中。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39405912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档