Database 大型联接表和扩展 问题
我们有一个快速增长的数据库,其中有几个大型联接表(目前有几十亿行),但随着这些表的增长,查询时间也受到了影响。问题是,随着更多数据添加到这些联接表链接的表中,联接表将继续以更快的速度增长,并对查询速度产生不利影响 背景 我正在处理一个存储基因组信息的数据库。与存在DNA变异的基因座相对应的许多标记(~300万)与在这些基因座上确定基因型的个体相关。每个标记都有许多可能的基因型,每个个体都必须有一个 目前的执行情况 当数据库(postgresql)仍然很小时,使用外键将基因型链接到标记上,然后通过联接表将个体链接到其基因型上是没有问题的。这样,就很容易查找个人的所有基因型,或者查找所有具有特定基因型的个人 下面列出了这些表格的精简版本:Database 大型联接表和扩展 问题,database,database-design,relational-database,Database,Database Design,Relational Database,我们有一个快速增长的数据库,其中有几个大型联接表(目前有几十亿行),但随着这些表的增长,查询时间也受到了影响。问题是,随着更多数据添加到这些联接表链接的表中,联接表将继续以更快的速度增长,并对查询速度产生不利影响 背景 我正在处理一个存储基因组信息的数据库。与存在DNA变异的基因座相对应的许多标记(~300万)与在这些基因座上确定基因型的个体相关。每个标记都有许多可能的基因型,每个个体都必须有一个 目前的执行情况 当数据库(postgresql)仍然很小时,使用外键将基因型链接到标记上,然后通过
Table "public.genotypes"
Column | Type | Modifiers
------------------+-----------------------------+--------------------------------------------------------
id | integer | not null default nextval('genotypes_id_seq'::regclass)
ref_variation_id | integer |
value | character varying(255) |
Indexes:
"genotypes_pkey" PRIMARY KEY, btree (id)
"index_genotypes_on_ref_variation_id" btree (ref_variation_id)
Table "public.genotypes_individuals"
Column | Type | Modifiers
---------------+---------+-----------
genotype_id | integer |
individual_id | integer |
Indexes:
"index_genotypes_individuals_on_genotype_id_and_individual_id" UNIQUE, btree (genotype_id, individual_id)
"index_genotypes_individuals_on_genotype_id" btree (genotype_id)
Table "public.individuals"
Column | Type | Modifiers
---------------+-----------------------------+----------------------------------------------------------
id | integer | not null default nextval('individuals_id_seq'::regclass)
hap_id | character varying(255) |
population_id | integer |
sex | character varying(255) |
Indexes:
"individuals_pkey" PRIMARY KEY, btree (id)
"index_individuals_on_hap_id" UNIQUE, btree (hap_id)
目前的瓶颈是查找每个个体的所有基因型,并按其位置进行排序。这是经常使用的,比从基因型中查找个体更重要。其中一些查询的示例如下:
- 对个人所有基因型的简单查找
选择*从“基因型”内部连接“基因型”上的“基因型个体”。id=“基因型个体”。基因型id其中(“基因型个体”。个体id=2946)SELECT * FROM "genotypes" INNER JOIN "genotypes_individuals" ON "genotypes".id = "genotypes_individuals".genotype_id WHERE ("genotypes_individuals".individual_id = 2946 )
- 通常情况下,虽然这会受到限制,因为有很多基因型。我们通常只对特定染色体上的基因感兴趣 从“基因型”的“基因型”内部连接“基因型个体”。id=“基因型个体”。基因型id,其中(“基因型个体”。个体id=2946)和(“基因型”。参考变量(37142,37143,…)
- 我们还需要偶尔走另一条路 选择*从“个体”内部连接“个体”上的“基因型个体”。id=“基因型个体”。个体id其中(“基因型个体”。基因型id=53430)
我知道数据库是为了高效地处理大型表而设计的,但由于驱动器IO,我们已经遇到了瓶颈。一个单独的查询仍然无关紧要,但1000个查询加起来很快。我们可以通过将数据库分布到多个驱动器上,在某种程度上缓解这个问题。然而,我想看看是否还有其他选择。我一直在想,是否有可能以某种方式将联接表条目按单个_id分隔开来,这可能会通过向联接表中添加额外的单个基因型行而不影响从个体到基因型的查找。或者指数已经这样做了 >你看了吗? < P>我会考虑测试一个使用自然键而不是ID号的模式。 您对个人所有基因型的查找
SELECT *
FROM "genotypes"
INNER JOIN "genotypes_individuals"
ON "genotypes".id = "genotypes_individuals".genotype_id
WHERE ("genotypes_individuals".individual_id = 2946 )
变成
SELECT *
FROM genotypes_individuals
WHERE (individual_id = 2946)
有时候这样更快。有时候不是
在我们的生产系统中,切换到自然关键点将平均性能提高了10倍。有些查询使用自然键运行速度快100倍,因为自然键消除了许多连接。有些查询也运行得较慢。但是平均速度还是令人印象深刻。您能描述一下这个连接中包含的表,以及您使用的索引类型吗?如果你也发布了实际的查询,也不会有什么坏处:)我编辑了原始帖子,以包含一些更具体的信息。希望有帮助。谢谢。你说查询时间随着表的增长而减少。随着表增长到数十亿行,硬件是否也在增长?是的,硬件已经升级,例如将数据库移动到ssd驱动器。我们目前正在重新升级。然而,我们也应该能够从数据库设计的角度来解决这个问题。谢谢这正是我想到的,但我不知道它叫什么。我将开始探索这一点,看看它是如何发展的。目前我唯一担心的是,由于我没有直接编写SQL语句(我使用Rail的活动记录,因为我们正在进行基于web的数据可视化),这两者可能不会很好地结合在一起。i、 e.您必须让触发器管理数据的插入和更新,以便将数据放入正确的表中。