0

我正在处理一些相当大的搜索功能查询。有许多不同的输入,因此查询非常大。它已经发展到有 2 层深的嵌套子查询的地方。性能已经成为那些将返回大型数据集并且可能必须筛选大量记录才能做到这一点的问题。比较少的那些表现很好,但其中一些变得非常糟糕。该数据库是 DB2 并且具有所有必要的索引,因此这不应该成为问题。我想知道如何最好地编写/重写这些查询以执行,因为我不太确定优化器将如何处理它。我显然不能在这里倾倒整个东西,但这里有一个例子:

Select A, B 
from TableA
      --A series of joins--
WHERE TableA.A IN (
      Select C 
      from TableB
              --A few joins--
      WHERE TableB.C IN (
              Select D from TableC
              --More joins and conditionals--
              )
       )

还有很多条件句贯穿始终,其中绝大多数是简单的相等。你明白了。子查询不向初始查询提供任何数据。它们的存在只是为了过滤结果。我早期遇到的一个问题是后端被编写为包含许多部分查询字符串,这些字符串被组装到最终查询中(由于搜索选项有 100 多种可能的组合,编写查询根本不可行对于每个),这使整个方法有点复杂。我想知道 EXISTS 而不是 IN 是否可能在一个或两个级别上有所帮助,或者另一组连接而不是子查询,或者可能在 TableC 的初始查询之上使用 WITH 等。我肯定希望消除瓶颈并希望人们可能对如何处理这个问题有任何反馈。

我可能还应该补充一点,两个子查询中都有潜在的联合。

4

2 回答 2

0

我发现“IN”谓词适用于小型子查询,“EXISTS”适用于大型子查询。尝试使用“EXISTS”谓词执行大型查询。

SELECT A, B 
FROM TableA
WHERE EXISTS (
      Select C 
      FROM TableB
      WHERE TableB.C = TableA.A)
于 2013-03-13T05:50:03.533 回答
0

改用内部连接可能会有所帮助。

Select A, B
from TableA
  inner join TableB on TableA.A = TableB.C
  inner join TableC on TableB.C = TableC.D

数据库是为连接而设计的,但优化器可能无法确定它可以将索引用于子查询。相反,它可能会尝试运行子查询,将结果保存在内存中,然后进行线性搜索以评估每条记录的 IN 运算符。

现在,您说您拥有所有必要的索引。考虑一下。

如果一个可选条件是 TableC.E = 'E' 而另一个可选条件是 TableC.F = 'F',那么同时包含这两个条件的查询将需要字段 TableC.ETableC.F 的索引。现在许多年轻的程序员认为他们可以在 TableC.E 上拥有一个索引,在 TableC.F 上拥有一个索引,这就是他们所需要的。事实上,如果查询中有两个字段,则需要在两个字段上都有一个索引。

因此,对于 100 多个组合,“所有必要的索引”可能需要 100 多个索引。

现在 TableC.E 上的索引,TableC.F 可以在有 TableC.E 条件但没有 TableC.F 条件的查询中使用,但不能在有 TableC.F 条件但没有 TableC.E 条件时使用。

数百个索引?我要做什么?

在实践中,它并没有那么糟糕。假设您有 N 个可选条件,它们要么在 where 子句中,要么不在。组合的数量是第 2 到第 n 个,或者对于数百个组合,N 是组合数量的 log2,介于 6 和 10 之间。此外,这些 log2 条件分布在三个表中。一些数据库支持多表索引,但我不确定 DB2 是否支持,所以我会坚持使用单表索引。

所以,我要说的是,对于 TableC.E 和 TableC.F 示例,仅具有以下索引是不够的:

TableB ON C
TableC ON D
TableC ON E
TableC ON F

一方面,优化器必须选择要使用的最后三个索引之一。最好将 D 字段包含在最后两个索引中,这给了我们

TableB ON C
TableC ON D, E
TableC ON D, F

在这里,如果字段 E 和 F 都不在查询中,它仍然可以在 D 上建立索引,但如果其中一个在查询中,它可以同时在 D 和另一个字段上建立索引。

现在假设您有 10 个字段的索引,这些字段可能在查询中,也可能不在查询中。为什么索引中只有一个字段?为什么不按出现在查询中的可能性降序添加其他字段?

在规划索引时考虑这一点。

于 2013-03-12T18:36:02.427 回答