DISTINCT有多慢?

时间:2009-01-12 05:32:21

标签: sql tsql

我可以选择为数据库结构编写两种不同的格式:

Article
-------
ArticleID int FK

Article_Tags
------------
ArticleTagID int FK
ArticleID int FK
TagText varchar(50)

Article
-------
ArticleID int PK

Article_Tags
------------
ArticleTagID int PK
ArticleID int FK
TagText varchar(50) FK

Tag
---
TagText varchar(50) PK

如果我想要数据库中所有标签的列表,我可以使用:

select distinct tagtext from article_tags

或:

select tagtext from tag

第一种情况非常简单。如果我正确索引它可能会加速。第二个是有点难,因为我必须不断删除没有连接的标签。想象一个相当大的系统,这会更好。

5 个答案:

答案 0 :(得分:4)

我会选择哪种解决方案为您的应用提供最佳/最干净的设计。如果您需要将数据直接附加到标记,那么单独的表(即更规范化的解决方案)将是正确的。

我会警告不要过多地担心2个提议的解决方案中的性能差异,如果编入索引,差异可能是微不足道的(两者都是相当常见的用例,并且可以使用标准数据库技术轻松优化)。在基于性能的两个呈现选项之间做出决定听起来像是过早的优化。

答案 1 :(得分:1)

选项2进行了一些修改。假设您将输入限制为标记表中包含的值,那么您可以为不同目的执行两个不同的查询。

第一个查询将为您提供所有当前USED标记的唯一列表。

第二个查询将为您提供可以使用的所有可能标记,包括尚未使用的标记。

最好使用标记ID并在标记和article_tags表之间建立关系。这将使选项2更有效,因为索引只是一个整数而不是一个字符串。

答案 2 :(得分:1)

我会选择

Article
-------
ArticleID int PK

Article_Tags
------------
ArticleTagID int PK
ArticleID int FK
TagId int FK

Tag
---
TagId int identity(1,1) PK
TagText varchar(50) 

没有理由从此开始对此进行反规范化。 (您的第一个和第二个版本未规范化)

在单独的表中使用标记很好,并且获取唯一标记更清晰,没有那个明确的语句。

如果应用了正确的索引,如果3个选项中的任何一个将执行几乎相同的性能。

答案 3 :(得分:1)

要回答标题中的基本问题:DISTINCT通常意味着对数据进行排序。根据索引,查询的结构和返回的数据量可能是免费的(tagtext上的正确索引,ORDER BY tagtext,小返回集)或不(缺少索引,顺序无关,大量返回集)。 / p>

答案 4 :(得分:1)

维护两个表的开销不太可能是弄乱简单设计的合理权衡。

如果你真的担心它会很简单地测试它,但根据我的丰富经验,毫无疑问这是真的。