非典型查询,必要索引,优化

时间:2018-02-16 14:19:19

标签: mysql sql indexing query-optimization

select ip.ns, ip.u from iparts ip where ip.isF = 0 and ((ip.wl < ?1 and ip.wl > ?2) or (ip.wf = 0 and ip.c < ?1 and ip.c > ?2))

ip.isF = 0 - 这部分是最具选择性的,95%的记录有isF = 1,但这个表格真的很大

如何优化此查询? 你能澄清一下我应该添加哪个索引 - iparts?

1 个答案:

答案 0 :(得分:1)

以下索引应该对您的查询有所帮助:

(`isF`,`wl`)

(`isF`,`wf`,`c`)

添加SELECTed列将进一步改进它,使这些索引覆盖索引,因此只允许使用索引,而无需查找主表。

(`isF`,`wl`,`ns`,`u`)

(`isF`,`wf`,`c`,`ns`,`u`)

使用这对索引而不是另一对索引的唯一缺点是插入时间可能会因为额外的列而稍微变慢,并且这些索引将占用更多空间。

我还建议您更改查询,以便充分利用这些索引。

SELECT ip.ns,
ip.u 
FROM iparts ip 
WHERE ip.isF = 0 
AND ip.wl < ?1 
AND ip.wl > ?2
UNION DISTINCT
SELECT ip.ns,
ip.u 
FROM iparts ip 
WHERE ip.isF = 0 
AND ip.wf = 0 
AND ip.c < ?1 
AND ip.c > ?2

通过使用UNION,RDBMS可以使用适合每个查询的索引单独进行每个查询。如果您的数据保证在两个查询之间没有重复,您可以将UNION DISTINCT更改为UNION ALL并节省更多时间。

注意:您不需要两对索引。我建议尝试第一对(较短的一对)并查看性能是否可接受(确保使用我的查询。)如果不够好,则删除它们并添加第二对。

如果您需要更多帮助,请将SHOW CREATE TABLE iparts的输出添加到您的问题中。这将让我们看到现有的索引和列数据类型,这两者都与任何优化相关。