我可以在 MySQL 中为 composite/multi-column 索引设置多订单索引吗?

Can I have multi-order index for composite/multi-column index in MySQL?

我有一个 invoices table 这样的:

| id   | client_id | is_recurring |
|----- |-----------| -------------|
| 1    | 2121      | 0            |
| 2    | 7434      | 1            |

现在在我的整个申请过程中,我可能会有以下疑问:

select * from invoices where client_id = 2121 and is_recurring = 0;

select * from invoices where is_recurring = 0 and client_id = 2121;

或 where 子句的任何其他顺序。

我已经在 client_id 和 is_recurring 上分别建立了索引。

但是对于复合索引,我应该在

上创建复合索引吗?
compost_index('client_id','is_recurring')

compost_index('is_recurring','client_id')

或两者?

请注意,两者的顺序不同。那么对于不同顺序搜索的表现呢?我应该用多个 order/direction 创建复合索引吗?

更新: 此外,如果我有一个 date 列,我将使用它来比较或多或少或排序依据,我应该使用哪些复合索引组合?

作为一个粗略的经验法则,您可能希望通过首先放置更严格(更高基数)的列来在两列索引中获得更好的性能。所以,我建议:

CREATE INDEX ON invoices compost_index (client_id, is_recurring)

如果使用此索引,MySQL 仅通过 client_id 过滤即可丢弃大部分索引。另一方面,is_recurring 列大概只采用 0 和 1 这两个值。因此,按此过滤可能不允许在扫描索引时丢弃许多记录。

WHERE 顺序;
任一 INDEX 顺序 - 无论基数如何;见
也就是说,either WHEREeither INDEX.
处理得同样好 既不是单列索引 - 它们可能会妨碍。

同时,复合索引也处理了相应的单列需求。也就是说,INDEX(a,b) 处理需要 INDEX(a) 的情况,但不处理需要 INDEX(b) 的情况。

为此:

 where client_id = 2121 and is_recurring = 0 and date > '2021-04-28';

使用了新规则:

INDEX(client_id, is_recurring,  -- in either order
      date)                     -- then the range test

即把所有用=(或IS NULL)测试的列放在最前面;然后你就有机会添加一个范围测试。

where client_id = 2121 and date > '2021-04-28' -- (client_id, date)
where client_id = 2121 order by date > '2021-04-28'
          -- also (client_id, date), but now the order is required
where client_id = 2121
  and date > '2021-04-28'
  order by date    -- again (client_id, date), specific ordering
where client_id = 2121
  and is_recurring = 0
  and date > '2021-04-28';  -- back to the 3-column one above

= 测试是一回事;所有不等式测试都是“范围”。

更多:http://mysql.rjweb.org/doc.php/index_cookbook_mysql