我正在测试Ingres Vectorwise数据库,试图找到一种更快的方式来运行查询,因为我们一直在经历一些与文本查找相关的缓慢。
下面的实现#1非常快,如果我基于一个char()列查找大约5000个项目。不幸的是,查找50个条目所花费的时间与查找5000个条目所花费的时间差不多。
另一方面,实现#2对于50个条目非常快,但对于5000个条目根本无法扩展。
实现#3显然会比#1更糟糕,但我只是提供了我尝试过的例子。
我的问题是:假设我的表只有两列,q = bigint, r = char()字段,你能想到使用基本SQL编写此查询的任何其他方式,以便我可以有更多的选择吗?我希望有一个选项可以合理地执行50和5000(一个像你在数据库中期望的那样扩展)。
请注意,我将接受执行相同功能的替代查询的任何答案;越多越好。我不指望任何一个会以我所希望的方式发展,但我不会知道,直到我尝试更多。
实现# 1:
select q
from test_table
where r in ('a', 'b', 'c', 'd', 'e')
实现# 2:select q
from test_table
where r = 'a' or r = 'b' or r = 'c' or r ='d' or r = 'e'
实现# 3:select q
from test_table a
where exists (
select r
from testtable
where r in ('a', 'b', 'c', 'd', 'e')
and a.r = r)
Vectorwise不"像您期望的那样缩放",因为它没有b树索引。与大多数列式分析dbms一样,它使用每个块的高值和低值元数据来选择读取哪些块。当从一个非常大的表中取出许多行时,这提供了出色的性能,但是在取出几行时性能很差,因为它将犁过许多不需要的行。
您可以通过在'r'上对表进行排序来进行优化,无论是手动还是使用"create index"命令(这将防止第一次加载后的批量加载)。这将使元数据更加精确,因此将读取更少的块。
我注意到示例中只有两列,没有连接和聚合函数。列式数据库真的是你所需要的还是Lucene更合适?
我只能建议在实现#2中使用联合/联合,因为联合可能比OR更快。我更喜欢执行#1。它应该使用索引并且应该足够快。例如,从Oracle 10g开始,它将自动重写IN子查询以使用EXISTS.
select q
from test_table
where r = 'a'
UNION ALL
select q
from test_table
where r = 'b'
....
UNION操作符选择不同的行。UNION ALL选择所有行,包括重复行。