在大型表(> 1M)上进行MySQL查询的最佳键

时间:2016-01-11 11:34:19

标签: mysql sql optimization indexing

我的查询执行时间太长(超过300秒)。可以使用索引或查询修改进行优化吗? 什么是最好的钥匙?

SELECT
    `streams_channel`.`id`,
    `streams_channel`.`uid`,
    `streams_channel`.`provider_id`
FROM
    `streams_channel`
WHERE
`streams_channel`.`provider_id` = 1
         AND 
`streams_channel`.`followers` < 50
ORDER BY `streams_channel`.`id` ASC
LIMIT 15000 OFFSET 1440000;

3 个答案:

答案 0 :(得分:1)

此查询的最佳索引可能是streams_channel(provider_id, followers, id)。您还可以添加uid,以便索引涵盖查询(即,所使用的所有列都在索引中)。

但是,此索引不会阻止ORDER BY的最终排序,这可能是性能问题。如果没有LIMIT,查询将返回多少行?

streams_channel(provider_id, id, followers, uid)上的索引可能会阻止排序。您需要测试数据。

答案 1 :(得分:0)

您需要WHERE子句中列的索引。

您可以通过在之前和之后运行EXPLAIN来查看更改的效果。您应该通过添加索引来查看TABLE SCAN。

WHERE条款的顺序很重要。使第一个子句消除大多数行,并使后续子句更容易。

答案 2 :(得分:0)

OFFSET 1440000杀死表演!即使使用完美索引,查询也必须查看1440000 + 15000行;这需要很多时间。

但有一种方法可以优化LIMIT 15000 OFFSET 1440000 - 请参阅Remember where you left off

正如我在Index Cookbook中讨论的那样,最佳指数是

INDEX(provider_id, followers)

provider_id首先是因为“=”; followers之后没有任何内容,因为它被测试为'范围'(&lt;)。

或(略好一点),您可以提供“覆盖”索引:

INDEX(provider_id, followers, id, uid)

这样所有工作都在索引中完成。两个额外的列iduid可以按任意顺序排列,但必须在其他两个列之后。

你在做什么来处理结果中的15K行?这会扼杀客户吗?