编写相同SQL查询以进行性能分析/测试的其他方法

时间:2013-03-01 15:12:55

标签: sql database ingres vectorwise

我正在测试一个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)

2 个答案:

答案 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快。