列上的索引只有2个不同的值

时间:2010-03-23 18:18:08

标签: sql performance oracle indexing

我想知道这个指数的表现:

我有一个“无效”varchar(1)列,它有2个值:NULL或'Y' 我有一个索引(无效),以及(无效,last_validated) Last_validated是一个日期时间(这用于不相关的SELECT查询)

我在表格中标记了少量项目(1-5%),并将其标记为“要删除”。
当我

时就是这样
 DELETE FROM items WHERE invalid='Y'

它不会对无效项目执行全表扫描。

问题似乎是,实际的DELETE现在非常慢,可能是因为删除了所有索引。

位图索引会为此提供更好的性能吗?或者根本没有索引?

5 个答案:

答案 0 :(得分:2)

正如Peter所说,首先要验证索引是否用于删除是很重要的。位图索引将调用DML的其他锁定,这可能会损害整体性能。

其他注意事项:

  • 是否有未编入索引的外键 从其他人引用此表 表?
  • 此表上有触发器 正在执行其他DML?

答案 1 :(得分:1)

应该使用索引,但DELETE仍然需要一些时间。

查看DELETE的执行计划:

EXPLAIN PLAN FOR
  DELETE FROM items WHERE invalid='Y';

SELECT * FROM TABLE( dbms_xplan.display );

您可以尝试使用位图索引,但我怀疑它会对性能产生太大影响。


使用NULL作为值不是一个好主意。查询

SELECT something FROM items WHERE invalid IS NULL

将无法使用您的索引,因为它只包含非空值。

答案 2 :(得分:0)

对此有两点想法......

  1. 使用NULL表示与'Y'相反的可能不是一个好主意。 Null表示*我不知道这个值是什么'或'没有有意义的答案一个问题'。你应该使用'N'作为'Y'的反面。这样可以消除搜索有效项的问题,因为当Oracle只包含非空值时,Oracle不会使用该列的索引。

  2. 您可以考虑在此列上添加CHECK CONSTRAINT ,以确保只输入合法值。

  3. 然而,这些变化都不一定会对DELETE性能产生任何影响。

答案 3 :(得分:0)

删除索引(无效)并尝试SELECT和DELETE。您已经有索引(invalid,last_validated)。您不应该单独使用无效索引。此表中大约有多少行?

答案 4 :(得分:0)

我建议:

  1. 检查您希望DELETE影响的记录数(即可能有超出预期的数量)
  2. 如果应删除的行数相对较少,请检查DELETE实际上是否正在使用invalid上的索引
  3. 跟踪会话以查看它正在做什么 - 它可能正在从磁盘读取比预期更多的块,或者它可能正在等待(例如记录锁定或闩锁争用)
  4. 在了解实际情况之前,不要打扰删除或创建索引。您可以进行各种更改,看到改进(但不知道为什么会有所改进),然后几个月就会出现问题再次出现或更糟糕。