0

我有一张invoices这样的桌子:

| 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')

或两者?

请注意,两者的顺序不同。那么对于不同订单搜索的性能呢?我应该创建具有多个顺序/方向的复合索引吗?

更新: 另外,如果我有一个date列用于比较更大或更小或排序,我应该使用哪些复合索引组合?

4

2 回答 2

2

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

CREATE INDEX ON invoices compost_index (client_id, is_recurring)

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

于 2021-10-27T04:59:41.167 回答
1

无论是在哪里订购;
任一 INDEX 订单 - 无论基数如何;见证明
即,任一被 WHERE一处理得同样好。 都不是单列索引 - 它们可能会妨碍您。 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

也就是说,将所有用=(or 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

于 2021-10-27T05:51:25.937 回答