我不是db guy。但我需要创建表并对它们执行CRUD操作。如果我默认在所有列上创建索引,我会感到困惑 或不?这是我在创建索引时考虑的理解。
索引基本上包含内存位置范围(第一个值存储的起始内存位置到最后一个值所在的结束内存位置) 存储)。因此,当我们在表索引中插入任何值时,需要更新列,因为它有一个值但是更新了列 价值不会对指数价值产生任何影响。 对吗?所以底线是我的列用于两个表之间的连接时我们应该考虑的 在连接中使用的列上创建索引但是可以跳过所有其他列,因为如果我们在它们上创建索引,则将涉及额外的成本 在列中插入新值时更新索引值。对吗?
考虑这种情况,表mytable
包含两列,即col1
,col2
,col3
。现在我们触发此查询
select col1,col2 from mytable
现在有两种情况。在第一种情况下,我们在col1
和col2
上创建索引。在第二种情况下,我们不创建任何索引。**根据我的理解
情况1将比case2快,因为在情况1中我们oracle可以快速找到列内存位置。所以这里我没有使用任何连接列但是
仍然索引在这里帮助。那么我应该考虑在这里创建索引吗?**
如果在上面的相同场景中,如果我们开火
,该怎么办?select * from mytable
而不是
select col1,col2 from mytable
这里的索引会有帮助吗?
答案 0 :(得分:29)
不要在每列中创建索引!它会减慢插入/删除/更新操作的速度。
作为一个简单的提醒,您可以在WHERE
,ORDER BY
和GROUP BY
子句中常见的列中创建索引。您可以考虑在用于关联其他表的列中添加索引(例如,通过JOIN
)
示例:
SELECT col1,col2,col3 FROM my_table WHERE col2=1
在这里,在col2上创建索引将有助于此查询。
另外,考虑索引选择性。简单地说,在具有“大域”的值上创建索引,即Ids,名称等。不要在男性/女性列上创建它们。
答案 1 :(得分:14)
但列值的更新不会对索引值产生任何影响。正确?
没有。更新索引列会产生影响。 Oracle 11g performance manual声明:
修改索引列的INSDATE语句以及INSERT和DELETE 修改索引表的语句需要的时间比有的时间长 没有索引。这样的SQL语句必须修改索引和数据中的数据 表。他们还创建了额外的撤消和重做。
所以底线是当我的列用于两个表之间的连接时,我们应该考虑在连接中使用的列上创建索引但是可以跳过所有其他列,因为如果我们在它们上创建索引,则将涉及更新索引值的额外成本当在列中插入新值时。正确?
不只是插入,而是任何其他数据操作语言语句。
考虑这种情况。 。 。索引会在这里帮忙吗?
关于最后一段,为什么不构建一些具有代表性数据量的测试用例,以便证明或反驳您应该索引哪些列的假设?
答案 2 :(得分:3)
在您提供的特定方案中,没有WHERE子句,因此将使用表扫描或将使用索引扫描,但您只删除一列,因此性能可能不同。在第二种情况下,不应使用索引,因为它没有覆盖并且没有WHERE子句。如果有WHERE子句,索引可以允许过滤减少需要查找以获取缺失列的行数。
Oracle有许多不同的表,包括堆或索引组织表。
如果索引覆盖,则更有可能使用它,尤其是在选择性时。但请注意,当WHERE子句中存在约束并且覆盖索引中的列比基表中的列少得多时,索引组织表并不比堆上的覆盖索引更好。
创建具有比实际使用的列更多的列的索引只有在它们更有可能覆盖索引时才有用,但添加所有列将类似于索引组织表。请注意,Oracle没有相当于SQL Server的INCLUDE(COLUMN),它可以用来使索引更具覆盖性(它有效地创建了仅列的一个子集的附加聚簇索引 - 如果您希望索引是唯一的,则非常有用)还添加了一些您不希望在唯一性中考虑的数据,但有助于使其涵盖更多查询)
您需要查看您的计划,然后确定索引是否有用。然后看看计划,看看他们是否有所作为。