AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-54892

pietrop's questions

Martin Hope
pietrop
Asked: 2016-09-25 05:18:33 +0800 CST

同一列上存在两种不同类型索引时的 PostgreSQL 行为

  • 4

如果我在同一列上创建两个(或更多)不同类型的索引,PostgreSQL 会如何表现?

在我的例子中,我想将 B-Tree 索引与tsvector列上的 GIN 进行比较。我知道 GIN 专门用于tsvector. 奇怪的是,如果我创建 B-Tree 索引,PostgreSQL 不会抱怨,但我发现查询计划器没有使用它。我还可以创建一个 GIN 索引(无需删除 B-Tree 索引),现在规划器使用新创建的索引。该列现在有两个索引,但只使用了其中一个。

即使存在两个以上的索引,用于选择一个索引类型与另一个索引类型的标准是什么?为什么 PostgreSQL 不告诉我 a 上的 B-Tree 索引tsvector是无用的并且永远不会被规划器使用?

更新
GIN 索引仅用于某些检查条件,my_tsvector IS NOT NULL但(显然)不用于my_tsvector @@ '...'::tsquery.

postgresql index
  • 1 个回答
  • 884 Views
Martin Hope
pietrop
Asked: 2016-01-25 03:36:45 +0800 CST

PostgreSQL - 简单的列绑定

  • 0

我有许多相同长度(行数)的表,这些表以前在写入磁盘时按某些列排序。

我SELECT的形式是:

SELECT t1.id, t1.value, t2.value, t3.value, ...
FROM t1 LEFT JOIN t2 ON t1.id=t2.id
        LEFT JOIN t3 ON t1.id=t3.id
        ...

我知道这些表是如何填充的,这个结果完全对应于简单的列绑定,因此ON t1.id=t2.id可以ON t1.id=t3.id省略。问题是,据我所知,RDBMS 只能操作投影和行绑定。列绑定不是典型的操作。

所以问题如下:是否可以在不指定任何连接条件的情况下“按原样”绑定列?例如,以下语法错误的查询应该解释我的意思:

SELECT t1.id, t1.value, t2.value, t3.value, ...
FROM t1 COLUMN_BIND t2 COLUMN_BIND t3 ...

我正在使用 PostgreSQL 9.4.5。

数据示例

输入表:

t1.id | t1.value
----------------
    1 |       a
    2 |       a
    3 |       b
    4 |       a
    5 |       c
    6 |       a

t2.id | t2.value
----------------
    1 |       g
    2 |       g
    3 |       h
    4 |       g
    5 |       o
    6 |       l

t3.id | t3.value
----------------
    1 |       e
    2 |       e
    3 |       e
    4 |       e
    5 |       q
    6 |       e

预期结果:

t1.id | t1.value | t2.value | t3.value
--------------------------------------
    1 |       a  |        g |       e
    2 |       a  |        g |       e
    3 |       b  |        h |       e
    4 |       a  |        g |       e
    5 |       c  |        o |       q
    6 |       a  |        l |       e
postgresql join
  • 3 个回答
  • 2612 Views
Martin Hope
pietrop
Asked: 2016-01-21 05:13:27 +0800 CST

在不同事务中使用时,CREATE FUNCTION 和 DROP FUNCTION 是否锁定?

  • 2

我在 PostgreSQL 9.4.5 上遇到锁定问题。我同时运行两个或多个事务(通常有 2 个同时运行,但有时会发生 2 个以上)从相同的表读取但在不同的输出表上写入。在我的交易中,我有几个声明某些功能的语句DROP FUNCTION IF EXISTS。CREATE OR REPLACE FUNCTION

我的猜测是,DROP FUNCTION IF EXISTS并且CREATE OR REPLACE FUNCTION正在锁定。我对吗?我可以通过将语句移到事务之外来解决问题。

我观察到以下情况:两个事务 A 和 B 包含一些DROP FUNCTIONand CREATE OR REPLACE FUNCTION;如果我在事务 A 仍在运行时执行事务 B,则事务 B 会等待DROP FUNCTION它遇到的第一条语句。

postgresql transaction
  • 1 个回答
  • 1163 Views
Martin Hope
pietrop
Asked: 2015-12-15 15:54:31 +0800 CST

PostgreSQL 中日期范围的奇怪 upper() 行为

  • 1

我正在运行 PostgreSQL 9.4.5,我刚刚从这个查询中得到了一个意外的结果:

select  upper(('[2005-12-01,2005-12-04]')::daterange)

它返回2005-12-05而不是2005-12-04.

)以下查询通过指定而不是来排除上限]:

select  upper(('[2005-12-01,2005-12-04)')::daterange)

它返回2005-12-04。

该upper()函数不应该返回给定范围的上限吗?如果是这样,通过指定[2005-12-01,2005-12-04]为范围,它应该返回上限,即2005-12-04. 它2005-12-05反而返回,这对我来说很奇怪。

关于为什么会发生这种情况的任何解释?我只知道它'[2005-12-01,2005-12-04]'::daterange被 PostgreSQL 翻译成'[2005-12-01,2005-12-05)'::daterange,但这并不能解释为什么2005-12-05当我明确指定2005-12-04为上限时应该是上限。

postgresql postgresql-9.4
  • 1 个回答
  • 894 Views
Martin Hope
pietrop
Asked: 2015-11-07 05:34:45 +0800 CST

OS X、PostgreSQL 9.4.5 上的 psql“无效客户端编码”错误

  • 2

我目前正在运行一个 OS X Lion Server 系统,该系统附带一个内置且不可升级的 PostgreSQL 版本。经过多年的使用,我最终决定离开内置版本并安装一个独立版本。我禁用了内置安装并从 EDB 下载了安装程序并按照向导进行操作。在许多关于编码和语言环境的问题之后,我终于设法设置一个没有语言环境和 UTF8 编码的数据库。我发出了以下命令:

initdb -D /path/to/data --no-locale --encoding=UTF8

如果我使用 pgAdminIII 连接,我不会遇到任何问题。该命令show client_encoding;显示UNICODE为 pgAdminIII 使用的编码(默认安装给了我一个SQL_ASCII编码,这就是我运行该initdb命令的原因)。

问题是我无法使用psql. 无论我传递给它,我都会收到以下错误:

psql: invalid connection option "client_encoding"

我在 Internet 上进行了搜索,但没有找到任何可以解决我的问题的方法(例如发布env PGCLIENTENCODING=UTF8和添加client_encoding=UTF8到postgresql.conf)。

otool -L /Library/PostgreSQL/9.4/bin/psql返回:

/Library/PostgreSQL/9.4/bin/psql:
    @loader_path/../lib/libpq.5.dylib (compatibility version 5.0.0, current version 5.7.0)
    @loader_path/../lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
    @loader_path/../lib/libedit.0.dylib (compatibility version 1.0.0, current version 1.48.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)

任何人都可以帮我弄清楚吗?

非常感谢所有 Pietro

更新

我在编辑 bash 配置文件后忘记注销然后登录。Daniel Vérité 的建议是正确的。我只是编辑了DYLD_LIBRARY_PATHenv 变量,/etc/profile以使其在全局级别可见,而不仅仅是从交互式 shell 中可见。

我将以下行添加到/etc/profile:

export DYLD_LIBRARY_PATH='/Library/PostgreSQL/9.4/lib'

我希望这对其他人有帮助。

丹尼尔,非常感谢

postgresql configuration
  • 1 个回答
  • 1841 Views
Martin Hope
pietrop
Asked: 2015-03-28 04:01:35 +0800 CST

无法使 Dell PE T420 (Perc H710) 的性能优于带有 PostgreSQL 的 MacMini

  • 4

几个月来我一直在尝试解决 PostgreSQL 的性能问题。

系统配置

我们的部署机器是 Dell PowerEdge T420,配备 Perc H710 RAID 控制器,配置如下:

  • VD0:两块15k SAS磁盘(ext4,OS分区,WAL分区,RAID1)
  • VD1:10个10k SAS磁盘(XFS,Postgres数据分区,RAID5)

该系统具有以下配置:

  • Ubuntu 14.04.2 LTS (GNU/Linux 3.13.0-48-generic x86_64)
  • 128GB 内存(DDR3、8x16GB @1600Mhz)
  • 两个 Intel Xeon E5-2640 v2 @2Ghz
  • 具有 512MB RAM 的 Dell Perc H710(写入缓存:“WriteBack”,读取缓存:“ReadAhead”,磁盘缓存:“已禁用”):
    • VD0(OS 和 WAL 分区):两个 15k SAS 磁盘(ext4,RAID1)
    • VD1(Postgres 数据分区):十个 10k SAS 磁盘(XFS,RAID5)
  • PostgreSQL 9.4(已更新至最新可用版本)
  • 将 pg_stat_tmp 移动到 RAM 磁盘

我个人的低成本低配置开发机器是这样配置的 MacMini:

  • OS X 服务器 10.7.5
  • 8GB 内存(DDR3、2x4GB @1333Mhz)
  • 一个英特尔 i7 @2.2Ghz
  • 两个用于操作系统分区的内部 500GB 7.2k SAS HDD(非 RAID)
  • 外部 Promise Pegasus R1 与 Thunderbolt v1 连接(512MB RAM,四个 1TB 7.2k SAS HDD 32MB 缓存,RAID5,写入缓存:“WriteBack”,读取缓存:“ReadAhead”,磁盘缓存:“启用”,NCQ:“启用”)
  • PostgreSQL 9.0.13(OS X Server 附带的原始内置)
  • 将 pg_stat_tmp 移动到 RAM 磁盘

到目前为止,我已经对两台机器进行了大量调优调整,包括官方 Postgres 文档站点上的内核推荐调整。

应用

部署机器运行一个 web 平台,该平台指示 Postgres 进行超过十亿条记录的大交易。这是一个为一个用户设计的平台,因为由于数据大小,系统资源必须尽可能多地专用于一个单一的工作(我不喜欢称它为大数据,因为大数据是十亿的数量级)。

问题

我发现部署机器比开发机器慢很多。这是矛盾的,因为两台机器在很多方面确实不同。我运行了很多查询来调查这种奇怪的行为,并做了很多调优调整。

在过去的两个月里,我准备并执行了两种类型的查询集:

  • 答:这些套装使用SELECT ... INTO、CREATE INDEX和。CLUSTERVACUUM ANALYZE
  • B:这些集合来自我们的应用程序生成的事务,并利用SELECT集合 A 创建的表。

A 和 B 在 T420 上总是比较慢。唯一更快的操作类型是VACUUM ANALYZE.

结果

A型套装:

  • T420:从 311 秒(默认postgresql.conf)到 195 秒,对 RAID、内核和进行调优调整postgresql.conf;
  • MacMini:40 秒。

B型套装:

  • T420:141秒;
  • MacMini:101 秒。

我不得不提一下,我们还调整了 T420 上的 BIOS,将所有可能的参数设置为“性能”并禁用低能耗配置文件。这将 A 类集的执行时间从 240 秒减少到 211 秒。

我们还将所有固件和 BIOS 升级到最新可用版本。

以下是使用生成的两个基准pg_test_fsync:

T420pg_test_fsync

60 seconds per test
O_DIRECT supported on this platform for open_datasync and open_sync.

Compare file sync methods using one 8kB write:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                   23358.758 ops/sec      43 usecs/op
        fdatasync                       21417.018 ops/sec      47 usecs/op
        fsync                           21112.662 ops/sec      47 usecs/op
        fsync_writethrough                            n/a
        open_sync                       23082.764 ops/sec      43 usecs/op

Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                   11737.746 ops/sec      85 usecs/op
        fdatasync                       19222.074 ops/sec      52 usecs/op
        fsync                           18608.405 ops/sec      54 usecs/op
        fsync_writethrough                            n/a
        open_sync                       11510.074 ops/sec      87 usecs/op

Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16kB
in different write open_sync sizes.)
         1 * 16kB open_sync write       21484.546 ops/sec      47 usecs/op
         2 *  8kB open_sync writes      11478.119 ops/sec      87 usecs/op
         4 *  4kB open_sync writes       5885.149 ops/sec     170 usecs/op
         8 *  2kB open_sync writes       3027.676 ops/sec     330 usecs/op
        16 *  1kB open_sync writes       1512.922 ops/sec     661 usecs/op

Test if fsync on non-write file descriptor is honored:
(If the times are similar, fsync() can sync data written
on a different descriptor.)
        write, fsync, close             17946.690 ops/sec      56 usecs/op
        write, close, fsync             17976.202 ops/sec      56 usecs/op

Non-Sync'ed 8kB writes:
        write                           343202.937 ops/sec       3 usecs/op

苹果机pg_test_fsync

60 seconds per test
Direct I/O is not supported on this platform.

Compare file sync methods using one 8kB write:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                      3780.341 ops/sec     265 usecs/op
        fdatasync                          3117.094 ops/sec     321 usecs/op
        fsync                              3156.298 ops/sec     317 usecs/op
        fsync_writethrough                  110.300 ops/sec    9066 usecs/op
        open_sync                          3077.932 ops/sec     325 usecs/op

Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                      1522.400 ops/sec     657 usecs/op
        fdatasync                          2700.055 ops/sec     370 usecs/op
        fsync                              2670.652 ops/sec     374 usecs/op
        fsync_writethrough                   98.462 ops/sec   10156 usecs/op
        open_sync                          1532.235 ops/sec     653 usecs/op

Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16kB
in different write open_sync sizes.)
         1 * 16kB open_sync write          2634.754 ops/sec     380 usecs/op
         2 *  8kB open_sync writes         1547.801 ops/sec     646 usecs/op
         4 *  4kB open_sync writes          801.542 ops/sec    1248 usecs/op
         8 *  2kB open_sync writes          405.515 ops/sec    2466 usecs/op
        16 *  1kB open_sync writes          204.095 ops/sec    4900 usecs/op

Test if fsync on non-write file descriptor is honored:
(If the times are similar, fsync() can sync data written
on a different descriptor.)
        write, fsync, close                2747.345 ops/sec     364 usecs/op
        write, close, fsync                3070.877 ops/sec     326 usecs/op

Non-Sync'ed 8kB writes:
        write                              3275.716 ops/sec     305 usecs/op

这证实了 T420 的硬件 IO 功能,但不能解释为什么 MacMini 更快。

有任何想法吗?

更新 1

B 型集是交易,所以我不可能发布EXPLAIN ANALYZE结果。我从单个事务中提取了两个查询,并在两个系统上执行了两个查询。以下是结果:

T420

查询 B_1 [55999.649 毫秒 + 0.639 毫秒] http://explain.depesz.com/s/LbM

查询 B_2 [95664.832 毫秒 + 0.523 毫秒] http://explain.depesz.com/s/v06

苹果机

查询 B_1 [56315.614 毫秒] http://explain.depesz.com/s/uZTx

查询 B_2 [44890.813 毫秒]  http://explain.depesz.com/s/y7Dk

更新 2

我使用 gcc-4.9.1 和 Postgres 的不同参数组合编译了原始的 Postgres 9.4.1 源代码。我关注了这篇文章,但-flto由于make. 经过两天的测试,我在 T420 上从 195 秒下降到 189 秒,而 MacMini 是 40 秒(一套);从 141 到 129 秒,而 MacMini 是 101 秒(B 组)。我使用了以下编译选项:

./configure CFLAGS="-O3 -fno-inline-functions -march=native" --with-openssl --with-libxml --with-libxslt --with-wal-blocksize=64 --with-blocksize=32 --with-wal-segsize=64 --with-segsize=1

我还尝试使用第 N 个逻辑 CPU禁用超线程,echo 0 > /sys/devices/system/cpu/cpuN/online但B 集查询没有任何改变。cpuN我们有 2 个 8 核 CPU,总共 16 个物理核和 16 个逻辑核。

更新 3

这是之前的查询计划加上使用与 MacMini 相同配置的 T420 计划(但不同的 Postgres 版本);这样计划是相同的,除了性能。

T420 与 MacMini postgresql.conf

查询 B_1 [51280.208ms + 0.699ms] http://explain.depesz.com/s/wlb

查询 B_2 [177278.205ms + 0.428ms] http://explain.depesz.com/s/rzr

具有最佳 postgresql.conf 的 T420

查询 B_1 [55999.649 毫秒 + 0.639 毫秒] http://explain.depesz.com/s/LbM

查询 B_2 [95664.832 毫秒 + 0.523 毫秒] http://explain.depesz.com/s/v06

苹果机

查询 B_1 [56315.614 毫秒] http://explain.depesz.com/s/uZTx

查询 B_2 [44890.813 毫秒] http://explain.depesz.com/s/y7Dk


以下是用于所有测试的 T420 和 MacMini 的 postgresql.conf。

T420postgresql.conf

正常操作

autovacuum = on
maintenance_work_mem = 512MB
work_mem = 512MB
wal_buffers = 64MB
effective_cache_size = 64GB # this helps A LOT in disk write speed when creating indexes
shared_buffers = 32GB
checkpoint_segments = 2000
checkpoint_completion_target = 1.0
effective_io_concurrency = 0 # 1 doesn’t make any substantial difference
max_connections = 10 # 20 doesn’t make any difference

数据加载(与上面相同,但有以下更改):

autovacuum = off
maintenance_work_mem = 64GB

苹果机postgresql.conf

正常操作

autovacuum = on
maintenance_work_mem = 128MB
work_mem = 32MB
wal_buffers = 32MB
effective_cache_size = 800MB
shared_buffers = 512MB
checkpoint_segments = 32
checkpoint_completion_target = 1.0
effective_io_concurrency = 1
max_connections = 20

数据加载(与上面相同,但有以下更改):

autovacuum = off
maintenance_work_mem = 6GB
postgresql performance
  • 1 个回答
  • 1211 Views
Martin Hope
pietrop
Asked: 2015-02-28 02:58:36 +0800 CST

A 列上的聚集索引是否与创建 A 排序的表相同?

  • 3

在阅读9.0 版的官方 PostgreSQL 文档时,我读到了一个有趣的escamotage,它比CLUSTER大表表现得更好:

CLUSTER 命令通过使用您指定的索引扫描原始表来重新排序。这在大型表上可能会很慢,因为行是按索引顺序从表中获取的,如果表是无序的,则条目位于随机页面上,因此每移动一行都会检索一个磁盘页面。(PostgreSQL 有一个缓存,但大表的大部分内容不适合缓存。)集群表的另一种方法是使用:

  CREATE TABLE newtable AS
    SELECT * FROM table ORDER BY columnlist;

它使用 PostgreSQL 排序代码来生成所需的顺序;这通常比无序数据的索引扫描快得多。然后删除旧表,使用 ALTER TABLE ... RENAME 将新表重命名为旧名称,并重新创建表的索引。这种方法的最大缺点是它不保留 OID、约束、外键关系、授予的权限和表的其他辅助属性——所有这些项目都必须手动重新创建。另一个缺点是这种方式需要一个与表本身大小相同的排序临时文件,因此峰值磁盘使用量大约是表大小的三倍而不是表大小的两倍。

问题是这个建议没有出现在 > 9.0 版本的官方文档中。

我的问题是这个 escamotage 是否仍然对 9.1、9.2、9.3 和 9.4 有效,因为我被困CLUSTER在两个大表上的操作(一个有 ~750M 行,另一个有 ~1650M 行)和平均磁盘写入/读取由于CLUSTER官方文档中解释的算法,速度为 3MB/s 。对于大表来说,这是一个缓慢的过程,所以我想避免它执行“在索引关联列上创建有序表”的技巧。这将节省我几天的数据库处理时间。

postgresql clustered-index
  • 1 个回答
  • 2428 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve