db体系结构:一个表使用where vs多个表

bvuwiixz  于 2021-07-26  发布在  Java
关注(0)|答案(3)|浏览(418)

我想知道一个表有600万行(也就是一个巨大的db)和10万活跃用户有什么区别:

CREATE TABLE shoes (
id serial primary key,
color text,
is_left_one boolean,
stock int
);

还有6个索引,如:

CREATE INDEX blue_left_shoes ON shoes(color,is_left_one) WHERE color=blue AND is_left_one=true;

与:6个具有100万行的表:

CREATE TABLE blue_left_shoes(
id serial primary key,
stock int
);

后一种方法似乎更有效,因为用户不必询问条件,因为表就是条件,但是创建索引可能会减轻这一点?
此表用于查询左侧、右侧、“蓝色”、“绿色”或“红色”鞋子,并检查剩余商品的数量,但这是一个简化的示例,但您可以想到amazon(或任何数字销售平台)工具提示“仅剩下3个库存商品”来显示工作负载和用例。用户(每天有10万活跃用户)将进行查询。
注意:这个问题主要是针对postgresql的,但是与其他数据库的区别仍然是相关的和有趣的。

nwwlzxa7

nwwlzxa71#

在后一种情况下,使用一个名为 blue_left_shoes 您的代码需要首先确定要查看哪个表(而不是在where子句中参数化值)
随着排列和选项的增加,您需要增加表的数量,并增加应用程序中确定要使用哪个表的逻辑
任何需要使用这个数据库(即报告工具或api)的东西现在都需要重新实现所有这些规则
为了提高性能,您在高层应用了逻辑。
如果要对表进行适当的分区和/或索引,则会得到相同的效果—sql查询只查看重要的记录。不同之处在于,您不需要在更高的层中实现此逻辑
只要您能够正确地建立索引,保持这是一个表几乎总是正确的做法。

分区

数据库分区是您选择一个或多个列来决定如何“拆分”表的地方。在你的情况下,你可以选择(颜色,是左一)。
现在您的表以这种方式进行逻辑拆分和排序,当您搜索blue时,它会自动知道要查找哪个分区。它不会在任何其他分区中查找(这称为分区修剪)
请注意,这是根据搜索条件自动发生的。您不需要手动计算要查看的特定表。
分区不需要任何额外的存储(除了必须保存的各种元数据)
不能对一个表应用多个分区。只有一个

索引

创建索引还可以提高性能。但是索引占用空间,可能会影响插入和更新性能(因为它们需要维护)。实际上,select权衡几乎总是远远大于insert/update的负面影响
您应该在分区之前查看索引

非选择性索引

在您的特定情况下,需要考虑一件额外的事情:布尔字段不是“选择性的”。我将不深入讨论细节,但我只想说,您不应该单独在这个字段上创建索引,因为它不会被使用,因为它只会减少您必须查看的记录数的一半。您需要在任何索引中包含一些其他字段(即颜色)以使其有用

n9vozmp4

n9vozmp42#

通常,您希望将所有“like”数据保存在一个表中,而不是在多个表中拆分。这有很好的理由:
添加新的组合更容易。
保养table比较容易。
您可以轻松地跨实体进行查询。
总的来说,数据库效率更高,因为页面更有可能被填满。
还有其他原因。在您的例子中,您可能有一个将数据分成6个独立表的参数。这里的收益来自于没有 color 以及 is_left_one 在数据中。这意味着这些数据不会重复600万次。这样可以节省数十兆字节的数据存储。
我说最后一句话是开玩笑的(意思是我没那么认真)。现在的计算机有如此多的成员,以至于100mbytes在一般情况下并不重要。然而,如果你有一个严重的内存有限的环境(我认为“手表”在这里,甚至不是“智能手机”),那么它可能是有用的。
否则,分区是一个很好的解决方案,几乎可以满足您的需求。

juud5qan

juud5qan3#

为此:

WHERE color=blue AND is_left_one=true

最佳指标为

INDEX(color, is_left_one)  -- in either order

id 首先是没用的 WHERE .
有多个相同的表而不是一个表通常是不好的。

相关问题