MySQL order_by优化

时间:2017-04-09 14:48:19

标签: mysql sql-order-by

我们有一个复杂的查询,它使用表和order_by之间的连接。

以下示例:

select distinct `accounts`.`id`,
    `accounts`.`number_of_listings` as alias_0
from `accounts`
left outer join `revenue_item_account_leads` on `revenue_item_account_leads`.`account_id` = `accounts`.`id`
left outer join `matches` on `matches`.`matchable_id` = `accounts`.`id`
    and `matches`.`matchable_type` = 'Account'
where `accounts`.`locale_id` = 1
    and (
        revenue_item_account_leads.platform_id is null
        or (revenue_item_account_leads.platform_id != 6)
        )
    and (
        matches.matched_matchable_id is null
        or (
            matches.matched_matchable_id in (14, 31, 37)
            and matches.score < 0.75
            )
        or (matches.matched_matchable_id not in (14, 31, 37))
        )
    and (accounts.number_of_listings > 0)
order by `accounts`.`number_of_listings` desc LIMIT 25 OFFSET 0

没有order_by的查询在1秒内​​完成。 带有order_by的查询在5秒内完成(使其在生产中无法使用)。

已经有一个关于accounts.number_of_listings的索引。此外,还有我们加入的任何关联的索引。

关于如何改进这个的任何想法?

1 个答案:

答案 0 :(得分:0)

尝试以下查询

select distinct `accounts`.`id`, `accounts`.`number_of_listings` as alias_0
from `accounts`
left outer join `revenue_item_account_leads`
    on `revenue_item_account_leads`.`account_id` = `accounts`.`id`
    and revenue_item_account_leads.platform_id = 6
left outer join `matches`
    on  `matches`.`matchable_id` = `accounts`.`id`
    and `matches`.`matchable_type` = 'Account'
    and matches.matched_matchable_id in (14, 31, 37)
    and and matches.score >= 0.75
where `accounts`.`locale_id` = 1
    and accounts.number_of_listings > 0
    and revenue_item_account_leads.platform_id is null
    and matches.matched_matchable_id is null
order by `accounts`.`number_of_listings` desc LIMIT 25 OFFSET 0

这些指数:

accounts(locale_id, number_of_listings, id)
revenue_item_account_leads(account_id, platform_id)
matches(matchable_id, matchable_type, matched_matchable_id, score)

根据您的关系和数据,您甚至可能不需要DISTINCT关键字。