相关疑难解决方法(0)

测量 PostgreSQL 表行的大小

我有一个 PostgreSQL 表。select *很慢,但又select id好又快。我认为可能是行的大小非常大并且需要一段时间来运输,或者可能是其他一些因素。

我需要所有字段(或几乎所有字段),因此仅选择一个子集不是一个快速解决方案。选择我想要的字段仍然很慢。

这是我的表架构减去名称:

integer                  | not null default nextval('core_page_id_seq'::regclass)
character varying(255)   | not null
character varying(64)    | not null
text                     | default '{}'::text
character varying(255)   | 
integer                  | not null default 0
text                     | default '{}'::text
text                     | 
timestamp with time zone | 
integer                  | 
timestamp with time zone | 
integer                  | 
Run Code Online (Sandbox Code Playgroud)

文本字段的大小可以是任意大小。但是,在最坏的情况下,不会超过几千字节。

问题

  1. 有什么关于这叫“疯狂低效”的吗?
  2. 有没有办法在 Postgres 命令行中测量页面大小来帮助我调试?

postgresql performance size disk-space postgresql-performance

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

为读取性能配置 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万
查看次数

当所有值都是 36 个字符时,使用 char 和 varchar 进行索引查找会明显更快吗

我有一个旧模式(免责声明!),它使用基于哈希生成的 id 作为所有表的主键(有很多)。这种 id 的一个例子是:

922475bb-ad93-43ee-9487-d2671b886479
Run Code Online (Sandbox Code Playgroud)

改变这种方法是不可能的,但是索引访问的性能很差。撇开这可能的无数原因不谈,我注意到有一件事似乎不太理想 - 尽管所有许多表中的所有 id 值的长度都正好是 36 个字符,但列类型是varchar(36)而不是 char(36)

将列类型更改为固定长度是否会char(36)提供任何显着的索引性能优势,除了每个索引页的条目数量增加很小等之外?

即在处理固定长度类型时 postgres 的执行速度是否比处理可变长度类型快得多?

请不要提及微小的存储节省 - 与对列进行更改所需的手术相比,这无关紧要。

postgresql performance index varchar

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

索引:如果节点数相同,则整数与字符串性能

我正在使用 PostgreSQL (9.4) 数据库在 Ruby on Rails 中开发应用程序。对于我的用例,表中的列将被非常频繁地查找,因为应用程序的重点是在模型上搜索非常具体的属性。

我目前正在决定是对列使用integer类型还是简单地使用典型的字符串类型(例如character varying(255)这是 Rails 中的默认值),因为我不确定索引上的性能差异是什么。

这些列是 enums。对于它们可以拥有的可能值的数量,它们具有固定的大小。大多数枚举长度不超过 5,这意味着索引在应用程序的整个生命周期中或多或少是固定的;因此,整数和字符串索引在节点数上是相同的。

但是,将被索引的字符串可能有大约 20 个字符长,在内存中大约是整数的 5 倍(如果一个整数是 4 个字节,并且字符串是纯 ASCII 每个字符 1 个字节,那么这成立)。我不知道数据库引擎如何进行索引查找,但是如果它需要“扫描”字符串直到它完全匹配,那么本质上这意味着字符串查找将比整数查找慢 5 倍;整数查找匹配之前的“扫描”将是 4 个字节而不是 20 个。这就是我的想象:

查找值为(整数)4:

扫描………………………………………………………………………………………………………………………………………… 正在获取记录... |BYTE_1|BYTE_2|BYTE_3|BYTE_4|BYTE_5|BYTE_6|BYTE_7|BYTE_8|...|

查找值是(字符串)“some_val”(8 个字节):

扫描................................................. …………………………………………………………………………………………………………………………………………………………………… 正在获取记录... |BYTE_1|BYTE_2|BYTE_3|BYTE_4|BYTE_5|BYTE_6|BYTE_7|BYTE_8|...|

我希望这是有道理的。基本上,因为整数占用更少的空间,它可以比它的字符串对应物更快地“匹配”。也许这是一个完全错误的猜测,但我不是专家,所以这就是我问你们的原因!我想我刚刚找到的这个答案似乎支持我的假设,但我想确定一下。

列中可能值的数量在使用任何一个时都不会改变,因此索引本身不会改变(除非我向枚举添加了一个新值)。在这种情况下,使用integeror会有性能差异varchar(255),还是使用整数类型更有意义?


我问的原因是 Rails 的enum类型将整数映射到字符串键,但它们并不是面向用户的列。本质上,您无法验证枚举值是否有效,因为无效值会ArgumentError在运行任何验证之前导致。使用string类型将允许验证,但如果存在性能成本,我宁愿绕过验证问题。

postgresql performance index index-tuning query-performance

38
推荐指数
1
解决办法
3万
查看次数

如何在 PostgreSQL 中存储一字节整数?

在 PostgreSQL 文档中,据说整数数据类型可以存储在两字节、四字节或八字节的空间中。我的数据库中表的一列包含一个一字节整数值,我希望它以一字节数据类型存储。

  1. 在 PostgreSQL 中是否有使用单字节整数数据类型的扩展或方法?
  2. NUMERIC(1,0) 是多少字节?

postgresql datatypes storage postgresql-9.6

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

CHAR 与 VARCHAR (Postgres) 的索引性能

在这个答案(/sf/ask/36230561/)中,一个评论引起了我的注意:

还要记住,在进行索引比较时,CHAR 和 VARCHAR 之间通常存在很大差异

这是否适用/仍然适用于 Postgres?

我发现 Oracle 上的页面声称这CHAR或多或少是 for 的别名VARCHAR,因此索引性能是相同的,但我在 Postgres 上没有发现任何明确的内容。

postgresql performance varchar

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

为什么*不*错误:索引“foo”的索引行大小 xxxx 超过最大值 2712?

我们一再看到尝试索引值超过最大大小的列失败。Postgres 10 有这样的错误信息:

ERROR:  index row size xxxx exceeds maximum 2712 for index "foo_idx"
HINT:  Values larger than 1/3 of a buffer page cannot be indexed.
       Consider a function index of an MD5 hash of the value, or use full text indexing.
Run Code Online (Sandbox Code Playgroud)

例子:

等等。

现在,a_horse_with_no_name 演示了一个具有更大text值(10000 个字符)的案例,它似乎仍然适用UNIQUE于 Postgres 9.6 中的索引。引用他的测试用例:

create table tbl (col text);
create unique index on tbl (col);

insert into tbl
values (rpad(md5(random()::text), 10000, md5(random()::text)));

select length(val) …
Run Code Online (Sandbox Code Playgroud)

postgresql index size limits

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

列的数据类型会影响查询性能吗?

假设我有这张表:

Table "public.orders"
         Column      |     Type      | Collation | Nullable | Default 
    -----------------+---------------+-----------+----------+---------
     o_orderkey      | integer       |           | not null | 
     o_custkey       | integer       |           |          | 
     o_orderstatus   | character(1)  |           |          | 
     o_totalprice    | numeric(12,2) |           |          | 
     o_orderdate     | date          |           |          | 
     o_orderpriority | character(15) |           |          | 
     o_clerk         | character(15) |           |          | 
     o_shippriority  | integer       |           |          | 
     o_comment       | character(79) |           |          |
Run Code Online (Sandbox Code Playgroud)

如果我有涉及o_orderstatuso_orderpriority或列的查询,我可以将数据类型更改为 以改进它们吗o_clerko_commentchar(n)text

postgresql database-design optimization query-performance

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

当 PostgreSQL 的“类别”太多时,我应该使用枚举吗?

问题

我计划将包含更多 1000 万条记录的 CSV 加载到 PostgreSQL v12.1,其中一列具有“分类”值,因此为其创建枚举类型似乎是一个不错的选择,但它包含 208 个类别。

最短的字段为 2,最长的字段为 11 个字符。所有字段的平均值为 2.4。字符编码是 UTF8,但所有字符都是 ASCII

问题:

我应该使用enumeratedvarchar哪种类型?

附加信息

我丢弃char是因为官方 PostgreSQL 文档说明了有关charvarchartext 的以下内容

提示:这三种类型之间没有性能差异,除了使用空白填充类型时增加了存储空间,以及在存储到长度受限列时需要额外的一些 CPU 周期来检查长度。虽然 character(n) 在其他一些数据库系统中具有性能优势,但在 PostgreSQL 中没有这样的优势;事实上 character(n) 通常是三个中最慢的,因为它有额外的存储成本。在大多数情况下,应改用文本或字符变化。

PostgreSQL 中的枚举值在磁盘上占用4 个字节(请参阅 8.7.4. 实现细节)。考虑到这一点和使用enum类型的2.4 平均字符串长度会导致磁盘使用率略高(PostgreSQL 中的短字符串需要一个额外的字节磁盘空间)。我仍然有一种直觉,即使用 enum 是更好的选择,因为它的实现使许多针对它的操作更快。

postgresql performance import postgresql-performance

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

使用 PostgreSQL 存储布尔值的 smallint 和 bool 之间有什么区别?

smallint类型和bool存储布尔值的类型有什么区别?

这个问题出现在对地理信息系统堆栈交换问题的评论中。

postgresql datatypes

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