查询varchar与外键的性能



这是针对SQL Server的。

我有一个包含很多行的表,该表将被查询多次,所以我需要确保我的设计得到优化。

就这个问题而言,假设该表包含2列。名称和类型。名称是一个varchar,它将是唯一的。

类型可以是5个不同的值(type1…type5)。(未来可能包含更多值)

我应该将类型设置为varchar(并创建索引),还是最好创建一个包含5行的类型表,其中只有一列作为名称,并将类型设为外键?

两种方法的性能是否存在差异?查询并不总是具有相同的条件。有时它会用不同的值查询名称、类型或两者。

编辑:考虑一下,在我的应用程序中,如果类型是一个表,ID就会被缓存,这样我就不必每次都查询type表了。

严格来说,如果将所有数据保存在一个表中,您可能会获得更好的查询性能。然而,这样做被称为"反规范化",并伴随着许多相当严重的缺点。

  1. 如果你的表有"很多行",那么为每一行存储一个额外的varchar字段,而不是一个小的,甚至是tinyint,可以为你的表增加不小的大小
  2. 如果任何数据需要更改,您将不得不对该表执行大量更新。这意味着在修改锁定期间,事务日志增长和表上的潜在阻塞。如果您将其存储为一个单独的表,其中包含5行,如果您需要更新与该数据相关的数据,只需更新所需的5行中的一行即可
  3. 非规范化数据意味着该数据的定义不再存储在一个地方,而是存储在多个地方(实际上它存储在包含这些值的每一行中)
  4. 由于上面列出的所有原因,管理数据(插入、更新、删除,以及简单地定义数据)可能会很快变得比一开始就简单地正确规范化数据开销大得多,而且除了使用正确的索引之外,几乎没有任何好处

如果您发现需要同时返回"大"表和type表中的一些其他信息,并且您担心联接性能,老实说,这是不可能的。这是一个概括,但如果您的大表中有500M行,我看不出有多少用例需要返回所有这些行;你可能会得到一个子集。在这种情况下,该联接可能更易于管理。如果对type进行索引,那么联接应该很快。

如果你确实采用了去规范化数据的方法,我建议你仍然将查找表作为"类型"的"主定义",这样它就不会聚集数百万行的数据。

如果仍然希望在没有查找表的情况下取消数据的规范化,至少在列上设置一个CHECK约束,以限制哪些值是允许的或不允许的。

"很多行"是多少?。如果它是数十万或更多,那么Columnstore索引可能非常适合。

这取决于您的需要,但通常您希望type列为数值(在您的情况下为tinyint)。

最新更新