按我的第二张桌子的计数(*)排序需要很长时间

Posted

技术标签:

【中文标题】按我的第二张桌子的计数(*)排序需要很长时间【英文标题】:Order by count(*) of my second table takes long time 【发布时间】:2019-10-23 01:55:53 【问题描述】:

假设我有 2 张桌子。一个包含汽车制造商的名称及其 ID,第二个包含有关汽车型号的信息。我需要从第一个表中选择其中的几个,但按从第二个表数据链接的数量对它们进行排序。

目前,我的查询如下所示:

SELECT DISTINCT `manufacturers`.`name`, 
                `manufacturers`.`cars_link`, 
                `manufacturers`.`slug` 
FROM   `manufacturers` 
       JOIN `cars` 
         ON manufacturers.cars_link = cars.manufacturer 
WHERE  ( NOT ( `manufacturers`.`cars_link` IS NULL ) ) 
       AND ( `cars`.`class` = 'sedan' ) 
ORDER  BY (SELECT Count(*) 
           FROM   `cars` 
           WHERE  `manufacturers`.cars_link = `cars`.manufacturer) DESC 

对于我只有几十 mb 的踏板车来说,它工作正常。但是现在我需要为汽车表做同样的事情,它的大小只有几百兆字节。问题是查询需要很长时间,有时甚至会导致 nginx 超时。另外,我认为,我拥有所有必要的数据库索引。上面的查询有什么替代方法吗?

【问题讨论】:

manufacturers.cars_linkcars.manufacturer 是否已编入索引?如果不是,那很可能是问题所在。发布explain <your query> 的输出也会对我们有所帮助。 你为什么使用select distinct?样本数据、期望的结果以及对您想要做什么的解释都会有所帮助。 【参考方案1】:

让我们尝试使用子查询来代替您的计数。

select * from (
    select distinct m.name, m.cars_link, m.slug 
    from manufacturers m
    join cars c on m.cars_link=c.manufacturer
    left join
        (select count(1) ct, c1.manufacturer from manufacturers m1 
            inner join cars_link c2 on m1.cars_link=c2.manufacturer
            where coalesce(m1.cars_link, '') != '' and c1.class='sedan'
            group by c1.manufacturer) as t1
            on t1.manufacturer = c.manufacturer
    where coalesce(m.cars_link, '') != '' and c.class='sedan') t2
order by t1.ct

【讨论】:

以上是关于按我的第二张桌子的计数(*)排序需要很长时间的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery 查询需要很长时间

我想减少 MYSQL 查询执行时间。我的查询需要很长时间?

构建需要很长时间才能响应的 API 的最佳实践是啥?

使用 form-repeater 在填充的表中添加新行需要很长时间(10-15 秒) - jQuery

Exasol UPSERT 不使用第二张桌子?

每月最后一天加入第二张桌子