IS [NOT] NULL
插入Oracle中SQL语句的索引,有什么办法可以在SQL语句中替换IS NULL
吗?
根据Oracle 9i性能调优技巧和技巧,IS [NOT]为NULL会抑制列的索引。
例如:
select * from users where user_id is not null;
答案 0 :(得分:2)
您是否可以更改数据库结构?
如果是,为了在您的查询中没有任何WHERE column IS NULL
或WHERE column IS NOT NULL
条件,请完全规范化您的表格(即5NF或6NF)并制作所有内容条件NOT NULL
中使用的列。
我不是Oracle专家,但我严重怀疑Oracle等严重的RDBMS无法在可空列上使用索引。请参阅此问题和答案,以支持此观点。也许(您认为)您遇到的问题不是由列中的NULL
引起的,而是由它们的选择性引起的:oracle-10g-optimize-where-is-not-null
简单查询:
select * from users where user_id is not null;
如果选择性不够高,优化器将选择不使用索引 - 就像对任何其他查询一样。如果桌子上的Null很少,那么完全扫描表格会更快 - 或者至少优化器会这么认为。
答案 1 :(得分:2)
IS NOT NULL
你的说法不正确。 Oracle 将在该列上使用索引(前提是索引扫描确实比全表扫描更快 - 并非总是如此)
Oracle不会将全部为NULL的元组放入索引中,因此,如果您在单个列上定义索引,例如CREATE INDEX idx_user_id ON person (user_id)
该索引不包含user_id为NULL的行。因此,索引不能用于IS NULL
条件。
但是,如果需要进行频繁的IS NULL
选择,可以使用索引定义中的常量强制使用常量CREATE INDEX idx_user_id ON person (user_id, 1)
来索引空值,从而使用变通方法。该索引将用于IS NULL条件(再次提供其他访问方法效率不高)。
答案 2 :(得分:1)
没有改变数据就没有有效的方法来做同样的事情。
您可以使用魔术值而不是null,例如-1。这将允许您使字段不可为空,这会在一定程度上提高性能,并且对索引更有效。然而,这与通常的避免魔术值的建议相冲突,因此它是性能和最佳实践之间的折衷。