我正在测试一个Ingres Vectorwise数据库,试图找到一种更快的方式来运行查询,因为我们遇到了与文本查找相关的一些缓慢。
如果基于char()列查找大约5000个项目,下面的实现#1非常快。不幸的是,查找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)
答案 0 :(得分:2)
Vectorwise不会“像你期望的那样缩放”,因为它没有B树索引。它使用高值和低值的每块元数据来选择要读取的块,大多数柱状分析DBMS也是如此。当从一个非常大的表中提取许多行时,这会提供出色的性能,但是由于它会在很多不需要的行中进行操作,因此性能很差。
您可以通过手动或使用“create index”命令对“r”上的表进行排序来优化(这样可以防止第一次加载后的批量加载)。这将使元数据更精确,因此将读取更少的块。
我注意到示例中只有两列,没有连接,也没有聚合函数。一个柱状数据库真的是你需要的还是Lucene会更合适?
答案 1 :(得分:1)
我只能在实现#2中建议一个union / union,因为union可能比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选择所有行,包括重复行。 UNION ALL通常比UNION快。