我在一个Informix数据库上有一个包含5条million+记录的表。
这不是实际的表,但会显示我遇到的问题。
表:销售额
列: 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?
除了创建新的索引之外,还有其他解决方案吗?
谢谢。
发布于 2011-01-06 22:54:18
尝试使用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上的低基数索引。
附注:我的数据库中通常不会有允许空字符串、NULL和其他值的列。我可能会将该字段限制为BIT类型,如果您有它的话,使用1和0,默认值为0。
发布于 2011-01-06 23:07:48
“sale_confirmed”上的索引不太可能有用,因为“sale_confirmed”的基数似乎很低(NULL,是,否?)。更好的模式设计将在'sale_confirmed‘上强制执行NOT NULL,检查约束将强制执行'Y’或'N‘,除非您另行指定,否则默认值可能会给出'N’。这将避免必须对‘messy _confirmed’进行OR操作,这是很麻烦的。
Tim建议的UNION技术可能是一种不错的解决方法。
https://stackoverflow.com/questions/4615154
复制相似问题