5

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

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

4

9 回答 9

7

索引(或索引)并不糟糕。在过去的几十年里,许多非常聪明的人花费了大量的时间来确保这一点。

但是,您的架构缺乏相同的专业知识和努力,可能确实非常糟糕。

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

YMMV。

于 2009-03-25T16:51:50.893 回答
7

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

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

还有20张桌子?我建议您首先阅读数据库设计,或者向我们解释您的问题的背景。

于 2009-03-25T15:48:26.600 回答
3

简短的回答:索引是否糟糕:是和否

更长的答案:如果使用得当,它们不会很烂。也许你应该开始阅读索引是如何工作的、为什么它们可以工作以及为什么它们有时不工作。

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

于 2009-03-25T15:47:36.727 回答
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 和执行计划,它们会告诉您查询的持续时间、读/写次数和 CPU 使用率。执行计划还将告诉您正在使用哪些或 IF 索引。令您惊讶的是,您可能会看到表扫描,尽管您没有预料到。

于 2010-03-02T16:25:06.457 回答
2

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

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

索引不仅保留索引值,还保留某种指向行的指针(ROWIDin OracleLCIDin PostgreSQL,主键 inInnoDB等)。

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

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

在这种情况下,您将获得 20 个与原始索引大小相同的索引。

这种技术有时实际上用在所谓的分区索引中。它有它的优点和缺点。

于 2009-03-25T15:46:29.770 回答
2

Standard b-tree indexes are best suited to fairly selective indexes, which this example would not be. 你没有说你正在使用什么 DBMS;Oracle 有另一种类型的索引,称为位图索引,它更适合 OLAP 环境中的低选择性索引(因为这些索引的维护成本很高,因此不适合 OLTP 环境)。

优化器将根据统计数据决定是否认为索引有助于在最快的时间内获取数据;如果没有,优化器将不会使用它。

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

于 2009-03-25T15:51:30.960 回答
1

抱歉,我不太清楚你所说的“大”是什么意思。

  • 如果您的索引是聚集的,那么每条记录的所有数据都将位于同一叶页上,因此只要您正确编写查询,就可以为您的表创建最有效的索引。

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

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

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

于 2009-03-25T15:50:52.240 回答
0

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

至于磁盘使用情况,您必须权衡您的担忧。不同的 SQL 提供程序以不同的方式构建索引,但作为客户,您通常相信他们会尽力而为。在您所描述的情况下,聚集索引可能对于大小和性能都是最佳的。

于 2009-03-25T15:46:05.793 回答
0

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

假设您有 20 个不同的 4 个字符的字符串和 100 万行,那么保存这些值至少需要 400 万字节(如果是 16 位 unicode,则为 8 个字节)。

于 2009-03-25T15:46:46.820 回答