在Informix DB上使用索引(索引?)

时间:2011-01-06 13:01:32

标签: sql database indexing informix

我在Informix数据库中有一个包含500万条记录的表。

这不是实际的表格,但会显示我遇到的问题。

表:销售额 列:sale_id,sale_confirmed,vendor_id,purchaser_id
索引:idx1(sale_id),idx2(sale_confirmed),idx3(vendor_id),idx4(purchaser_id)

如果我这样做一个查询:

select *  
from sales  
where sale_confirmed IS NULL  
or sale_confirmed = '' 

然后查询在大约4或5秒内完成。

如果我这样做一个查询:

select *  
from sales  
where vendor_id = 12345 
or purchaser_id = 12345

然后查询在大约4或5秒内完成。

但是,如果我运行此查询(前两个查询的组合):

select *  
from sales  
where (sale_confirmed IS NULL  
        or sale_confirmed = '' )
and (vendor_id = 12345 
       or purchaser_id = 12345)

然后查询在我取消之前运行了15分钟。

数据库似乎不够聪明,不能串联使用不同的索引,即它似乎无法使用idx2来查找X行数并在该X行数内使用idx3和idx4 - 是的,我会认为这样做足够聪明吗?

在处理WHERE子句的第二部分时,有没有办法强制数据库使用idx3和idx4?

除了创建新索引之外的任何其他解决方案?

感谢。

2 个答案:

答案 0 :(得分:2)

尝试使用UNION,其中每个部分只需要选择两个索引:

select *  
from sales  
where (sale_confirmed IS NULL  
        or sale_confirmed = '' )
and vendor_id = 12345


UNION

select *  
from sales  
where (sale_confirmed IS NULL  
        or sale_confirmed = '' )
and purchaser_id = 12345

如果Informix支持内联视图,请根据供应商/购买者获取行集,然后从该集合中排除未经证实的销售。

select inlineview.*  from
(
select *  from sales  
where vendor_id = 12345 or purchaser_id = 12345
) as inlineview
where (sale_confirmed IS NULL or sale_confirmed = '')

最后,我想您可能希望在sale_confirmed上删除低基数指数。

P.S。我通常在我的数据库中没有允许空字符串,NULL和其他值的列。如果有的话,我可能会将字段限制为BIT类型,1和0,默认为0。

答案 1 :(得分:1)

'sale_confirmed'上的索引不太可能有用,因为'sale_confirmed'的基数似乎很低(NULL,是,否?)。更好的模式设计会在'sale_confirmed'上强制执行NOT NULL,并且CHECK约束会强制执行'Y'或'N',默认情况下可以给你'N',除非您另有指定。这样就可以避免在'sale_confirmed'上进行OR操作,这很麻烦。

Tim建议的UNION技术可能是一个不错的解决方法。