【问题标题】:Lots of foreign keys on one table - performance issue一张表上有很多外键 - 性能问题
【发布时间】:2019-09-08 16:36:53
【问题描述】:
我有一个大表,其中主要包含 枚举值(40 个不同的枚举)。
每个枚举值都是单独表的外键,因为我需要允许用户自定义名称并添加/删除新值。
这些枚举表非常小,每个表最多有 20 个值。
每个外键都有索引,所以总共有大约 50 个索引键。
这使得插入和更新非常缓慢。
主表中有大约 200 万行,并且它不断增长。
表示这些枚举值/提高性能的最佳做法是什么?
我应该删除一些在搜索期间不使用的索引键,只保留外键还是将主表拆分为多个表,方法是将共享的枚举分组一些“类别”?
【问题讨论】:
-
请edit您的问题并添加执行计划(如使用explain (analyze, buffers) insert ...生成的慢速插入和更新语句的formatted text - 不只是一个“简单”的解释
标签:
sql
database
postgresql
indexing
foreign-keys
【解决方案1】:
您有许多参考表,并且您的大型主表有指向每个参考表的列。这是设计一组表的常用方法。
你的异性恋关系有什么目的?它们强制数据库保持一致性,这可能很有用。例如,如果您的主表中有一个名为food_id 的列,并且它指向一个名为food 的六行表中的一行,那么您的 fk 关系将阻止您插入指向第八行的值.
但要确保一致性,需要对值进行大量检查。它使您的插入和更新变慢。你知道的。
我建议您简单地将所有外键关系从主表删除到引用表,并删除主表中这些列的索引。可能发生的最坏情况?您会在指向参考表中不存在的行的列之一中偶尔获得值。您可以通过以下方式缓解这种情况:
SELECT main.item, main.item2, COALESCE (food.name, '--missing--') name
FROM main
LEFT JOIN food on main.food_id = food.food_id
左连接将为缺少的food_id 值生成一个空值,COALESCE() 将显示一个默认值。
而且你的插入操作会变得很快。