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
    • 最新
    • 标签
主页 / dba / 问题 / 6912
Accepted
François Beausoleil
François Beausoleil
Asked: 2011-10-18 18:01:15 +0800 CST2011-10-18 18:01:15 +0800 CST 2011-10-18 18:01:15 +0800 CST

我是否应该花时间将列类型从 CHAR(36) 更改为 UUID?

  • 772

我的数据库中已经有几百万行了。当我设计我的架构时,我不知道 PostgreSQL UUID 数据类型。

其中一张表有 1600 万行(每个分片大约 350 万到 400 万条记录),每天增长大约 50 万条记录。如果需要,我仍然可以将生产系统关闭几个小时。我不会在一两个星期内享受这种奢侈。

我的问题是,这样做值得吗?我想知道 JOIN 性能、磁盘空间使用(完整的 gzip 转储为 1.25 GiB),以及这种性质的事情。

表架构是:

# \d twitter_interactions
                Table "public.twitter_interactions"
         Column          |            Type             | Modifiers 
-------------------------+-----------------------------+-----------
 interaction_id          | character(36)               | not null
 status_text             | character varying(1024)     | not null
 screen_name             | character varying(40)       | not null
 twitter_user_id         | bigint                      | 
 replying_to_screen_name | character varying(40)       | 
 source                  | character varying(240)      | not null
 tweet_id                | bigint                      | not null
 created_at              | timestamp without time zone | not null
Indexes:
    "twitter_interactions_pkey" PRIMARY KEY, btree (interaction_id)
    "twitter_interactions_tweet_id_key" UNIQUE, btree (tweet_id)
    "index_twitter_interactions_on_created_at" btree (created_at)
    "index_twitter_interactions_on_screen_name" btree (screen_name)
Triggers:
    insert_twitter_interactions_trigger BEFORE INSERT ON twitter_interactions FOR EACH ROW EXECUTE PROCEDURE twitter_interactions_insert_trigger()
Number of child tables: 9 (Use \d+ to list them.)
postgresql
  • 4 4 个回答
  • 3137 Views

4 个回答

  • Voted
  1. Best Answer
    Peter Eisentraut
    2011-10-18T20:00:24+08:002011-10-18T20:00:24+08:00

    我会考虑更改为 UUID 类型。 char(36)占用 40 个字节,uuid占用 16 个字节,因此每行将节省 24 个字节,这相当于每天 12 MB,一年后节省 4 GB。加索引。根据您拥有的硬件,这并不多,但它可能是。如果你有更多这样的改进机会,它就会增加。

    此外,我在您的架构中没有看到任何约束,以确保它interaction_id实际上是正确的格式。使用正确的类型也会给你。

    但是,如果您喜欢这样,那么使用bigint将节省更多并具有更好的性能。您的应用程序不太可能太大以至于bigintID 列不起作用。

    • 13
  2. billinkc
    2011-10-18T19:48:31+08:002011-10-18T19:48:31+08:00

    无论如何,我都不是 postgres 人,但根据我从 SQL Server 了解到的情况,您可以放入数据页的行越多,您将获得的性能越好(从磁盘读取数据通常是最昂贵的操作)。因此,从 36 个1字节宽的字段变为 16 字节GUID似乎可以直接节省成本。您可以进行的读取越少,返回结果的速度就越快。当然,所有这些都假设 GUID/UUID 满足表的业务需求。如果 UUID 满足它,那么bigint会满足吗?这将进一步减少每行 8 个字节的存储成本。

    编辑1

    对于Postgres 中的字符数据,它们需要额外的存储成本。127 个字节以下的短字符串有 1 个字节的开销,而任何更长的字符串有 4 个字节,这就是第二个响应者如何为 36 个字节的字段提出 40 个字节的成本。但是还有一个字符串压缩选项,所以也许它不会花费全部 40。我不知道最终成本是多少,但基本原理仍然存在:超过 16 字节的任何内容都会增加存储成本,读取时间更长并消耗更多内存。

    短字符串(最多 126 个字节)的存储要求是 1 个字节加上实际字符串,其中包括字符情况下的空格填充。较长的字符串有 4 个字节的开销,而不是 1 个。长字符串由系统自动压缩,因此对磁盘的物理要求可能会更少。

    • 6
  3. mrdenny
    2011-10-18T21:22:23+08:002011-10-18T21:22:23+08:00

    除了空间问题,请记住,您需要更改每个表以使用正确的数据类型,否则您的连接性能将严重下降。

    • 3
  4. Unreason
    2011-10-19T05:54:32+08:002011-10-19T05:54:32+08:00

    除了节省数据和索引的大小(正如其他人所说),这确实转化为 I/O 节省,您需要考虑的是您将如何生成新值interaction_id以及对索引和查询条件(连接)。

    对于索引 - 它会更小,但是如果您的很多查询使用索引扫描切换到 UUID 可能会导致索引扫描不可能(取决于您将如何生成 UUID)并且bigint可能是更好的选择。

    最后,由于实际的性能影响还取决于您的使用模式和数据分布,您应该运行测试并拥有一个可以测试您的更改的开发和测试环境。

    这将为您提供关于对性能的影响的更准确的答案。

    • 3

相关问题

  • 我可以在使用数据库后激活 PITR 吗?

  • 运行时间偏移延迟复制的最佳实践

  • 存储过程可以防止 SQL 注入吗?

  • PostgreSQL 中 UniProt 的生物序列

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

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

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

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

    • 4 个回答
  • Marko Smith

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

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +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
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +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