【问题标题】:How to use index properly for a large mysql table?如何为大型mysql表正确使用索引?
【发布时间】:2016-07-29 16:35:13
【问题描述】:

我在 MySQL 5.7.13 中有一个表,它有 3 列(实际上更多,但这三列用于搜索) - 它有一个列 company_id,它有一个列 department_id,它有列status。

现在,通常员工都是这样工作的,他们进入系统,选择合作的公司,选择部门(这是强制性的)。之后他们进入菜单,可以从表中获取数据而不指定状态,或者他们也可以指定他们想要什么状态?

由于mysql索引的前缀顺序,我使用复杂索引(company_id,department_id,status)似乎很自然。由于他们总是按公司和部门过滤,有时还会按状态过滤,所以一切似乎都很好。

但是,最近添加了一项新功能。还有一些特殊员工,与普通用户不同,他们只选择公司,而不选择部门。因此,他们的查询按公司和状态过滤。这意味着索引中断,它只会按公司过滤,而不是按状态过滤,因为部门被省略了。

对此有什么解决方法?我在这里看到两个解决方案。一是状态非常受限制-它基本上具有值-已创建(1),已发送(2),已接受(3),已拒绝(4)。所以,我可以创建索引(company_id、status、department_id),如果用户没有选择任何状态,我可以在查询中追加如下内容:

AND status in (1,2,3,4)

索引会为此有效吗?或者,其他解决方案是创建第二个索引并同时具有 (company_id, department_id, status) 和 (company_id, status, department_id),但是 mysql 优化器会选择正确的索引吗?我不确定,哪种方式更好,它们中的任何一种都可以工作。

【问题讨论】:

  • 表格有多少行?一家公司的典型行数是多少?最大值是多少? company+dept 是否只有一个 status?

标签: mysql indexing high-load


【解决方案1】:

据我所知,这应该可以正常工作。优化器将利用(x,y,z) 复合上的索引,并在需要时执行using index; using where。请注意,假设我的理解是组合的最左边部分已经是您的 where 子句的一部分,例如 x 允许 y 已经在组合中以供索引使用。

另一方面,如果IN 子句甚至很大,并且说在单列索引上,IN 将很快得到满足。请参阅我在这里写的答案:Index uses IN。

当然,请查看标题为 EXPLAIN Syntax 和类似 Using EXPLAIN to Write Better MySQL Queries 的 MySQL 手册页。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    相关资源
    最近更新 更多