如何在SQL select语句中避免IS [NOT] NULL?

时间:2011-09-06 07:05:00

标签: sql oracle null

IS [NOT] NULL插入Oracle中SQL语句的索引,有什么办法可以在SQL语句中替换IS NULL吗?

根据Oracle 9i性能调优技巧和技巧,IS [NOT]为NULL会抑制列的索引。

例如:

select * from users where user_id is not null;

3 个答案:

答案 0 :(得分:2)

您是否可以更改数据库结构?

如果是,为了在您的查询中没有任何WHERE column IS NULLWHERE column IS NOT NULL条件,请完全规范化您的表格(即5NF6NF)并制作所有内容条件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。这将允许您使字段不可为空,这会在一定程度上提高性能,并且对索引更有效。然而,这与通常的避免魔术值的建议相冲突,因此它是性能和最佳实践之间的折衷。