索引是否在SQL中吮吸?

时间:2009-03-25 15:43:21

标签: sql indexing partitioning

假设我有一个包含大量行的表,其中一个我想索引的列可以包含20个值中的一个。 如果我在列上放一个索引它会很大吗?

如果是这样,为什么?如果我将数据分成数据到20个表中,每个值对应一个列,索引大小将是微不足道的,但索引效果将是相同的。

9 个答案:

答案 0 :(得分:7)

这不是索引会吮吸。它正在将索引放在错误的列上,这将会很糟糕。

说真的,为什么你需要一个单列的表?这些数据的含义是什么?它的用途是什么?

还有20张桌子?我建议您先阅读database design,或者向我们解释您问题的背景。

答案 1 :(得分:7)

索引(或指数)不吸引人。很多非常聪明的人在过去的几十年里花了相当多的时间来确保这一点。

然而,你的架构缺乏相同数量的专业知识和努力,确实可能非常糟糕。

在所描述的情况下,分区等同于应用聚簇索引。如果表以其他方式排序(或以任意顺序排列),则索引必须占用更多空间。根据平台的不同,非聚集索引的大小可能会随着行的排序相对于索引值的增加而减小。

因人而异。

答案 2 :(得分:3)

答案简短: 索引很糟糕:是和否

答案越长: 如果使用得当,他们不会吮吸。也许你应该开始阅读索引如何工作,为什么它们可以工作以及为什么它们有时不起作用。

良好的起点: http://www.sqlservercentral.com/articles/Indexing/

答案 3 :(得分:3)

没有索引不会吮吸,但您必须注意使用它们的方式,否则它们可能会对您的查询性能产生误解。

第一:架构/设计
为什么要创建只有一列的表?这可能是规范化向前迈进了一步。数据库设计是优化性能时最重要的考虑因素之一

第二名:索引
简而言之,索引将帮助数据库对记录执行二进制搜索。如果没有列(或列集)的索引,数据库通常会回退到表扫描。表扫描非常昂贵,因为它涉及枚举每条记录。

对于索引扫描来说,数据库表中有多少条记录并不重要。由于(平衡)二叉树搜索加倍记录量只会导致一个额外的搜索步骤。

确定表的主键,SQL将自动在该列上放置聚簇索引。集群索引表现非常好。此外,您可以将非聚簇索引放在SELECT,JOIN,WHERE,GROUP BY和ORDER BY语句中经常使用的列上。请记住索引有一定的重叠,尽量不要将聚簇索引包含在非聚集索引中。

同样有趣的可能是索引的填充因子。您是否希望优化表的读取(高填充因子 - 更少的存储,更少的IO)或写入(低填充因子更多存储,更少重建数据库页)。

第三:分区
使用分区的一个原因是优化您的数据访问。假设您有100万条记录,其中500,000条记录不再相关,但存储用于存档。在这种情况下,您可以决定对表进行分区,并将500,000条旧记录存储在慢速存储上,将其他500,000条记录存储在快速存储区中。

衡量是知道
了解所发生情况的最佳方法是衡量你的cpu和io会发生什么。 Microsoft SQL Server具有一些工具,如Management Studio中的Profiler和Execution计划,它们将告诉您查询的持续时间,读/写次数和CPU使用情况。此外,执行计划将告诉您正在使用哪些或IF索引。令你惊讶的是,你可能会看到一个表扫描,尽管你没想到它。

答案 4 :(得分:2)

  

假设我有一个包含大量行和一列的表,我想索引它可以有20个值中的一个。如果我在列上放一个索引它会很大吗?

索引大小将与您的行数和索引值的长度成比例。

索引不仅保留了索引值,还保留了某一行指针(ROWID中的OracleLCID中的PostgreSQL,主键InnoDB等。)

如果您有10,000行和1个不同的值,则索引中仍会有10,000个记录。

  

如果是这样,为什么?如果我将数据分成数据到20个表中,每个值对应一个列,索引大小将是微不足道的,但索引效果将是相同的

在这种情况下,你会得到20个与原始索引大小相同的索引。

有时在这种被称为分区索引中使用此技术。它有其优点和缺点。

答案 5 :(得分:2)

标准b树索引最适合于相当选择性的索引,这个例子不是。你没有说你正在使用什么DBMS; Oracle有另一种称为位图索引的索引,它更适合OLAP环境中的低选择性索引(因为这些索引的维护成本很高,使得它们不适合OLTP环境)。

优化者将根据统计数据决定是否认为该指数有助于在最快的时间内获取数据;如果不能,那么optmiser将不会使用它。

分区是另一种策略。在Oracle中,您可以将表定义为在某些列上进行分区,并且优化器可以像您建议的那样自动执行“分区消除”。

答案 6 :(得分:1)

抱歉,我不太清楚“大”的意思。

  • 如果您的索引是群集的,则每条记录的所有数据都将位于同一页面上,从而为您的表创建最有效的索引,只要您正确地编写查询。

  • 如果您的索引是非群集的,那么只有与索引相关的数据才会出现在您的叶子页面上。然后,根据您拥有的其他索引数量以及填充因子等详细信息,您的索引可能会有效,也可能不会有效。一般来说,如果您的桌子上没有大量的索引,那么您应该是安全的。

  • 索引的效率也将取决于您所说的进入该列的20个值的数据类型。如果这些是预定义的值,那么它们的详细信息可能应该在具有简单主键数据类型(如Int / Number)的查找表中。然后将该列作为外键添加到表中,并在列上添加索引。

最终,你可以在列上找到完美的索引。但是最好的用途将在很大程度上取决于您编写的查询。因此,如果您的查询使用索引,那么您就是黄金。

答案 7 :(得分:0)

索引纯粹是为了表现。如果索引不能提高您感兴趣的查询的性能,那么它很糟糕。

至于磁盘使用情况,您必须权衡您的顾虑。不同的SQL提供程序以不同的方式构建索引,但作为客户端,您通常相信它们可以做到最好。在您描述的情况下,聚集索引可能对于大小和性能都是最佳的。

答案 8 :(得分:0)

它足够大,可以按排序顺序保存所有行的值。

假设您有20个不同的4个字符的字符串,以及100万行,它至少会有4百万个字节(如果是16位unicode,则至少为8个字节)来保存这些值。