我一直致力于为 DB2 LUW 数据库构建一些索引。我们已经为登录页面实现了一些新查询,我正在努力提高性能。我在一些表上发现了一些索引,它们的排序似乎不是最佳的,即选择性非常低的列比选择性高的列出现得更早。我希望用更好的版本替换它们,但我对连接索引有点困惑。
对于一些背景知识,查询并不复杂,尽管它们可能有点大:
SELECT
--About a dozen fields from TABLE A--
--A few fields from joined tables--
FROM
TABLE A
--A few inner join/left joins, mostly on A.ID1 and A.ID2, BIGINT generated keys--
WHERE
A.ONE = :x
AND A.TWO IN (:y)
AND A.THREE IN (--uncorrelated suquery--)
AND A.FOUR IS NULL
AND (A.FIVE BETWEEN :date1 AND :date2
OR
A.SIX = 'STUFF')
ORDER BY A.SEVEN
你明白了。大多数这些列的基数非常明显,并且很容易根据选择性来构建索引。以正确的顺序对 WHERE 子句中使用的所有字段进行索引在加快处理速度方面非常成功。但是,连接列有点令人困惑。
许多列本身已经建立了索引,包括 A.ID1 和 A.ID2,它们共同构成了表的主键。我认为这是一个聚集索引。还有一些自己索引的外键 ID 对。我想知道是否有必要甚至有用地将这些列包含在覆盖 WHERE 子句字段的索引中的连接中。我听说很多应该索引连接的列,应该索引 WHERE 子句列,它们是,但是分开的。我还没有真正找到关于该主题的任何确定性(或“通常是一个好主意,但并非总是”)。这种事情的一般做法是什么?如果查询很重要,则单独索引或将它们放在一起?
此外,A.SEVEN 是具有唯一值的列,但我们仅在 ORDER BY 中使用它。同样,我还没有完全找到任何确定的东西,但是它仅用于 ORDER BY (以及在 SELECT 语句中)这一事实是否会影响它在索引中的位置,而不管基数如何(即,它被放置在末尾索引,因为它不会用于过滤,仅用于排序,或者由于唯一性而将其放在开头),还是应该将其保留在单独的索引中?
作为事后的想法,列 A.FOUR 仅检查为空。这是否意味着任何非空数据的基数都无关紧要,因为我们只在寻找空值,所以它应该放在索引的后面?A.FOUR 可能大部分为空值,但当它不为空值时将在很大程度上是唯一的。