决定何时在数据库中的表列上创建索引?

Posted

技术标签:

【中文标题】决定何时在数据库中的表列上创建索引?【英文标题】:Decision when to create Index on table column in database? 【发布时间】:2011-12-06 08:10:02 【问题描述】:

我不是 db 家伙。但我需要创建表并对它们进行 CRUD 操作。如果我默认在所有列上创建索引,我会感到困惑 或不?这是我在创建索引时考虑的理解。

索引基本上包含内存位置范围(存储第一个值的起始内存位置到最后一个值的结束内存位置 存储)。因此,当我们在表索引中插入任何值时,列需要更新,因为它还有一个值,但列的更新 value 不会对索引值产生任何影响。 对吗? 所以底线是当我的列用于连接两个表时,我们应该考虑 在连接中使用的列上创建索引,但可以跳过所有其他列,因为如果我们在它们上创建索引,它将涉及额外的成本 在列中插入新值时更新索引值。对吗?

考虑这种情况,其中表mytable 包含两个三列,即col1col2col3。现在我们触发这个查询

select col1,col2 from mytable

现在这里有两种情况。在第一种情况下,我们在col1col2 上创建索引。在第二种情况下,我们不创建任何索引。**根据我的理解 case 1 会比 case2 快,因为在 case 1 中,我们 oracle 可以快速找到列内存位置。所以在这里我没有使用任何连接列但是 仍然索引在这里有所帮助。那么我是否应该考虑在这里创建索引?**

如果我们在上述相同的情况下开火会怎样?

select * from mytable

而不是

select col1,col2 from mytable

索引在这里有用吗?

【问题讨论】:

索引对 SELECT 子句中的值没有任何作用。重要的是您的 ON 子句或 WHERE 子句中的字段列表。 @Bill - Oracle 是否尽可能使用覆盖索引?我是一名 SQL Server 人员,我知道 Oracle 处理索引的方式略有不同,但我认为在某些情况下它仍然使用覆盖索引。 @Tom:嗯。每天学些新东西。我也是一个 MSSQL 人,不知道这一点。尽管如此,覆盖索引似乎只有在你做很多 R 而不是很多 CUD 时才有用。 @Bill - 是的。就像数据库世界中的许多事情一样,这都是一种平衡行为。最终的平衡取决于应用程序的具体情况。 blog.sqlauthority.com/2011/01/17/… 【参考方案1】:

不要在每一列中都创建索引!它会减慢插入/删除/更新操作的速度。

作为一个简单的提醒,您可以在WHEREORDER BYGROUP BY 子句中常​​见的列中创建索引。您可以考虑在用于关联其他表的列中添加索引(例如通过JOIN

例子:

SELECT col1,col2,col3 FROM my_table WHERE col2=1

在这里,在 col2 上创建索引将有助于此查询。

另外,请考虑索引选择性。简单地说,为具有“大域”的值创建索引,即 ID、名称等。不要在男性/女性列上创建它们。

【讨论】:

【参考方案2】:

但列值的更新不会对索引值产生任何影响。对吧?

没有。更新索引列会产生影响。 Oracle 11g performance manual 声明:

修改索引列以及 INSERT 和 DELETE 的 UPDATE 语句 修改索引表的语句比有 没有索引。此类 SQL 语句必须修改索引中的数据和 表。它们还会创建额外的撤消和重做。


所以底线是当我的列用于两个表之间的连接时,我们应该考虑在连接中使用的列上创建索引,但所有其他列都可以跳过,因为如果我们在它们上创建索引,它将涉及更新索引值的额外成本在列中插入新值时。对吧?

不仅仅是插入,还有任何其他数据操作语言语句。

考虑这种情况。 . .索引在这里有用吗?

关于最后一段,为什么不构建一些具有代表性数据量的测试用例,以便证明或反驳关于应该索引哪些列的假设?

【讨论】:

【参考方案3】:

在您给出的特定场景中,没有 WHERE 子句,因此将使用表扫描或索引扫描,但您只删除一列,因此性能可能没有那么不同.在第二种情况下,不应该使用索引,因为它没有覆盖并且没有 WHERE 子句。如果有 WHERE 子句,索引可以允许过滤减少需要查找的行数以获取丢失的列。

Oracle 有许多不同的表,包括堆或索引组织的表。

如果一个索引是覆盖的,它更有可能被使用,尤其是在有选择性的时候。但请注意,当 WHERE 子句中存在约束并且覆盖索引中的列远少于基表中的列时,索引组织的表并不比堆上的覆盖索引好。

创建具有比实际使用的更多列的索引只有在它们更有可能使索引覆盖时才有帮助,但添加所有列将类似于索引组织表。请注意,Oracle 没有与 SQL Server 的 INCLUDE (COLUMN) 等效的功能,它可用于使索引更具覆盖性(它有效地创建了仅包含列子集的附加聚集索引 - 如果您希望索引唯一但还添加一些您不想在唯一性中考虑但有助于使其覆盖更多查询的数据)

您需要查看您的计划,然后确定索引是否会有所帮助。然后看看之后的计划,看看他们是否有所作为。

【讨论】:

以上是关于决定何时在数据库中的表列上创建索引?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle创建索引SQL简单的例子,在表中的指定字段和如何使用索引呢?

如何在 MySQL 中的 json 列上创建索引?

在已有大量数据的表上创建 MySQL 索引

如何使用 xpath 表达式在 PostgreSQL 中的 XML 列上创建索引?

在已经存在主键或唯一键约束的列上创建索引

SQL Server的复合索引学习转载