我有一个包含三列的表:user_id, customer_id, and order_id
。
在我的查询中,我经常使用以下条件过滤数据:
... WHERE user_id = 23434 AND customer_id = 234234 AND order_id IN [23334, 23423, 23452];
我想通过在这些列上创建复合索引来优化查询性能,但我不确定这些列应按什么顺序包含在索引中。
考虑到列的选择性为customer_id
、ordre_id
和user_id
,创建复合索引的最佳顺序是什么?
我可以这样做(customer_id, order_id, user_id)
,但是这里要过滤出记录user_id
,数据库必须访问传递范围内的每个叶节点order_id
。
但是,如果我这样做(customer_id, user_id, order_id)
,这里它将扫描许多与 匹配的索引并进行过滤,然后从或user_id
获取行。我在这里不确定。如果有人可以提供更多这方面的信息。disk
shared_buffers
我应该根据色谱柱的选择性对它们进行优先排序还是采用不同的方法?
我更倾向于(customer_id, order_id, user_id)
,但我需要一些澄清。
只要与 进行比较,列的选择性并不重要
=
。我用粗体写下这一点,因为选择性很重要是 DBA 民间传说中常见但错误的元素。然而,重要的是进行比较的列
=
位于索引定义中的第一个列。因此,您只需确保这
order_id
是三列索引中的最后一列。为了扩大范围,在创建索引时只考虑单个查询很少是个好主意。您应该考虑现有索引和其余工作负载。让我举几个例子:
如果 上已有索引
user_id
,则应删除该索引并在 上创建一个索引(user_id, customer_id, order_id)
。摆脱索引是一个好处,可以保证索引中的特定列顺序。如果您的某些查询使用
WHERE
类似 的子句WHERE user_id IN (1, 2, 3) AND customer_id IN (4, 5, 6)
,您应该将更具选择性的列放在索引中的前面。对于除 之外的比较=
,这很重要。如果您已经在 上有一个索引
(customer_id, order_id)
,也许您不应该创建额外的索引。当然,该指数不会是完美的,但如果user_id
不是很有选择性,它可能就足够好了。