在处理数百万行的某些报告中,我们面临一些性能问题。我曾尝试优化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?
感谢您的时间
答案 0 :(得分:2)
您可以使用EXPLAIN query
来查看MySQL在执行时将执行的操作。这在尝试弄清为什么缓慢时会帮助很多。
JOIN-ing一次只出现一张表,该顺序由MySQL通过分析查询并尝试查找最快的顺序来确定。您将在EXPLAIN
结果中看到它。
每个JOIN只能使用一个索引,并且该索引必须在要连接的表上。在您的示例中,使用的索引将是表B上的id
(主键)。在每个FK上创建索引将为MySQL提供更多的查询计划选项,在某些情况下可能会有所帮助。
当联接表存在NULL(丢失行)时,WHERE和JOIN条件之间只有一个区别(INNER JOIN完全没有区别)。对于您的示例,b_id
上的索引不执行任何操作。如果将其更改为INNER JOIN(例如,通过在where子句中添加b.something = 42
),则如果MySQL确定应反向执行查询(第一个b,然后一个a),则可以使用它。
否。在多个索引中包含一列是100%可以的。如果您在(A,B,C)
上有一个索引,而在(A)
上又添加了一个 ,那么它将是多余且毫无意义的(因为它是另一个索引的前缀)。 B
上的索引非常好。