Mysql 行号的顺序非常慢

Posted

技术标签:

【中文标题】Mysql 行号的顺序非常慢【英文标题】:Mysql row number with order by very slow 【发布时间】:2021-05-23 11:47:41 【问题描述】:

我有这个问题

select courses.id, y.qs_world, courses.name_en as name, 
courses.description_en as description,
source_link, courses.slug, fee, duration, courses.university_id, college_id,
study_level_id, application_fee, courses.currency_id 
from courses
left join university_ranks as y on courses.university_id = y.university_id
and y.year = '2021' 
left join universities on courses.university_id = universities.id
left join countries on countries.id = universities.country_id where courses.status = 1

order by ROW_NUMBER() OVER (PARTITION BY countries.id ORDER BY courses.id)

此查询执行时间过长,但如果我删除最后一行,它运行良好。

我使用了索引,但没有什么不同。

EXPLAIN 注释是Using temporary,Using filesort,但我想改进查询而不使用temporaryfilesort

我怎样才能做到这一点?

更新: 我试过这个查询,但速度相同

SELECT * FROM (    
     SELECT
      `courses`.`id`,`courses`.`status`,  `y`.`qs_world`, `courses`.`name_en` as `name`, `courses`.`description_en` as `description`,
 `source_link`, `courses`.`slug`, `fee`, `duration`, `courses`.`university_id`, `college_id`,
 `study_level_id`, `application_fee`, `courses`.`currency_id`, `countries`.`id` as country_id
    FROM
      courses
      left join `university_ranks` as `y` on `courses`.`university_id` = `y`.`university_id`
 and `y`.`year` = '2021'
 left join `universities` on `courses`.`university_id` = `universities`.`id`
 left join `countries` on `countries`.`id` = `universities`.`country_id`
 
) UserCourse  where status = 1
order by ROW_NUMBER() OVER (PARTITION BY country_id ORDER BY id) 

【问题讨论】:

当我看到这个时,有两件事很突出:(1)WHERE status = 1 放错了位置。它应该是主查询的一部分,否则您会浪费大量时间来为状态不是1 / 的课程加入数据。 (2) 无需将主查询包装在另一个查询中。这只会增加不必要的复杂性。 但是问题出在order by 如果我删除它一切都会好的 如果您需要将同一国家/地区的所有记录组合在一起,您可以order by country_id, id。只要row_number中只有ID,这里看起来就没有其他具体逻辑了。 【参考方案1】:

countries.id 作为 country_id --> universities.country_id

然后删除

  left join  `countries`  ON `countries`.`id` = `universities`.`country_id`

where status = 1 移动到内部查询中。

好像

   order by  ROW_NUMBER() OVER (PARTITION BY country_id ORDER BY  id)

可以替换为

   ORDER BY country_id, id

摆脱外部查询

不要说LEFT,除非“右”表可能缺少行。 (它会让读者对你的意图感到困惑。)

【讨论】:

ORDER BY country_id, id 不会像我需要的那样工作,因为我需要对与下一行不同的国家/地区的每一行进行排序 @Decoder - 请提供一组简短的数据以及所需的结果。 删除左连接“国家”后一切正常

以上是关于Mysql 行号的顺序非常慢的主要内容,如果未能解决你的问题,请参考以下文章

mysql where执行顺序

mysql语句执行顺序

MySQL Left Join 运行速度非常慢,拆分为 2 个查询要快得多

多线程 ByteBuffers 比顺序慢?

MySQL存储写入速度慢分析

使用 SQL 查询表以非常特定的顺序显示数据