需要澄清索引(WHERE,JOIN)

时间:2019-01-30 14:29:04

标签: mysql sql query-optimization rdbms entity-attribute-value

在处理数百万行的某些报告中,我们面临一些性能问题。我曾尝试优化sql查询,但它只能将执行时间减少一半。

下一步是分析和修改或添加一些索引,因此我有一些疑问:

1- sql查询包含很多联接:我必须为每个外键创建一个索引吗?

2-想象一下请求SELECT * FROM A LEFT JOIN B on a.b_id = b.id where a.attribute2 = 'someValue',我们在表A上有一个基于b_id和attribute2的索引:我的请求是否将该索引用于where部分(我知道两个条件是否在where上)子句将使用索引)。

3-如果索引基于C1,C2和C3列,并且我决定添加基于C2的索引,我是否需要从第一个索引中删除C2?

感谢您的时间

1 个答案:

答案 0 :(得分:2)

您可以使用EXPLAIN query来查看MySQL在执行时将执行的操作。这在尝试弄清为什么缓慢时会帮助很多。

JOIN-ing一次只出现一张表,该顺序由MySQL通过分析查询并尝试查找最快的顺序来确定。您将在EXPLAIN结果中看到它。

  1. 每个JOIN只能使用一个索引,并且该索引必须在要连接的表上。在您的示例中,使用的索引将是表B上的id(主键)。在每个FK上创建索引将为MySQL提供更多的查询计划选项,在某些情况下可能会有所帮助。

    < / li>
  2. 当联接表存在NULL(丢失行)时,WHERE和JOIN条件之间只有一个区别(INNER JOIN完全没有区别)。对于您的示例,b_id上的索引不执行任何操作。如果将其更改为INNER JOIN(例如,通过在where子句中添加b.something = 42),则如果MySQL确定应反向执行查询(第一个b,然后一个a),则可以使用它。

  3. 否。在多个索引中包含一列是100%可以的。如果您在(A,B,C)上有一个索引,而在(A)上又添加了一个 ,那么它将是多余且毫无意义的(因为它是另一个索引的前缀)。 B上的索引非常好。