我正在处理基于用户选择多个值的登录页面的一些查询,并将它们触发到 DB2 数据库。我正在尝试将它们调整得尽可能快,并取得一些好的结果。但是,有几个查询的执行时间非常难看,比如 10 秒左右。我一直在仔细研究解释计划,并看到了一些相当奇怪的东西。
对于初学者来说,这些查询非常简单。有几个内连接、几个左连接和几个过滤条件。他们正在加入一些非常大的表(有些有大约 270 万行)并返回一些非常强大的数据集(最多 30k 行左右,可能有 15 列左右)。问题是,在检查解释计划时,我看到了一个非常奇怪的情况。这是一个 FETCH 操作,占用查询成本的 1/3 到 1/2。此 FETCH 与以下联接有关:
SELECT ...
FROM A
JOIN B
ON B.ID1 = A.ID1
AND B.ID2 = A.ID2
WHERE
B.FIELD IN (:parameter --No more than four strings in here)
A.ID1 和 2 是 A 的主键,但在 BBFIELD 中不是唯一的,总共可能包含十几个不同的字符串值,但表大约有 270 万行。我看到的是 B 上的一个 FETCH 操作,它包含一个 RIDSCN,它本身包含 B.FIELD IN 子句中每个参数的一个排序操作,每个排序都包含 B 上的索引扫描。令人担忧的是 FETCH 需要多少时间操作正在吃东西,特别是考虑到它是大约十几个连接之一。
我一直在研究索引并且有一些理论,但我不确定问题出在哪里,我自己不能应用任何索引,只能请求它们,所以有点痛苦。A 在 ID1 和 ID2 上编入索引。B 也在 ID1 和 ID2 上编入索引。在这些 SORT 操作中,有一个单独的索引用于 B.FIELD(还包含 B 中的一些其他字段)。但是,B 没有专门针对 ID1、ID2、FIEL 的索引。创建此索引是否会减少我在该 FETCH 操作中看到的时间?我不完全确定这是由于缺少适当的索引,或者仅仅是表的大小和列中数据的性质。我已经在几张桌子上请求了 runstats,看看他们是否会从重组中受益,但如果失败了,我 我希望有些人可能会有所启发。我对索引的应用和细微差别还是有点陌生。
编辑:这是解释计划的相关部分。可能值得注意的是,这是解释计划树中的第一个操作(如在一系列 NLJOIN、HSJOIN 等之后):
SCHEMA.B FETCH 35.1 % 177046.0625
RIDSCN 0.0 % 5716.63037109375
SORT 0.0 % 5257.94189453125
B.INDEX IXSCAN 1.0 % 5018.35009765625
SORT 0.0 % 385.5107116699219
B.INDEX IXSCAN 0.1 % 374.5053405761719
SORT 0.0 % 50.442073822021484
B.INDEX IXSCAN 0.0 % 50.34944152832031
SORT 0.0 % 22.738037109375
B.INDEX IXSCAN 0.0 % 22.73009490966797
问题是,我有一些其他查询在 IN 子句中没有显示这种成本,即使返回数千行也是如此。为一个连接使用三分之一的查询成本似乎过高。就像我之前说的,也许它与这个特定的表甚至额外的连接有更多的关系,但我真的很想找到一种方法来减少这个数字。