使用GROUP_CONCAT(MySQL中的密集排名)FIND_IN_SET太慢

时间:2017-11-24 07:26:23

标签: mysql sql

我有一个根据列值计算密集排名的查询:

SELECT id,
       score1, 
       FIND_IN_SET
       ( 
         score1, 
          ( 
            SELECT GROUP_CONCAT(score1  ORDER BY score1  DESC) FROM scores 
          ) 
       ) as rank 
FROM score_news;

这是查询结果的样子:

+----+--------+------+
| id | score1 | rank |
+----+--------+------+
|  1 |     15 |    1 |
|  2 |     15 |    1 |
|  3 |     14 |    3 |
|  4 |     13 |    4 |
+----+--------+------+

当分数增加N倍时,查询需要Nx更长的时间。有什么办法可以优化吗?我的桌子大小为10 6 功能

注意:我已经尝试过使用mysql用户变量的技术,但是当我在大型集合上运行它时会得到不一致的结果。经过调查,我在MySQL文档中发现了这一点:

  

用户变量的评估顺序未定义,可能会更改   基于给定查询中包含的元素。在SELECT @ a,@ a   := @ a + 1 ...,你可能会认为MySQL会首先评估@a和   然后做第二个任务,但更改查询(例如,通过   添加GROUP BY,HAVING或ORDER BY子句可能会改变顺序   评估...一般规则是永远不要为用户分配值   变量在一个语句的一部分中,并在一些语句中使用相同的变量   同一声明的其他部分。你可能会得到你的结果   期待,但这不能保证。

我尝试使用用户变量:

SELECT
      a.id,
      @prev := @curr as prev,
      @curr := a.score1 as curr,
      @rank := IF(@rank = 0, @rank + 1, IF(@prev > @curr, @rank+@ties, @rank)) AS rank,
      @ties := IF(@prev = @curr, @ties+1, 1) AS ties
    FROM
      scores a,
      (
        SELECT
          @curr := null,
          @prev := null,
          @rank := 0,
          @ties := 1,
          @total := count(*) 
        FROM scores 
        WHERE score1 is not null 
      ) b
    WHERE
      score1 is not null 
    ORDER BY
      score1 DESC
   ) 

2 个答案:

答案 0 :(得分:0)

带变量的解决方案可行,但您需要首先对结果集进行排序,只有然后才能使用变量赋值:

SELECT a.id,
       @rank := IF(@curr = a.score1, @rank, @rank + @ties) AS rank,
       @ties := IF(@curr = a.score1, @ties + 1, 1) AS ties,
       @curr := a.score1 AS curr
FROM   (SELECT * FROM scores WHERE score1 is NOT NULL ORDER BY score1 DESC) a,
       (SELECT @curr := null, @rank := 0, @ties := 1) b

注意:我将curr列放在select子句的最后一行以保存一个变量。

答案 1 :(得分:0)

您还可以使用以下查询来获取密集排名,而无需使用用户定义的变量

migrationBuilder.AddColumn<string>(
    name: "Id",
    table: "EventStaffRequest",
    maxLength: 450,
    nullable: false,
    defaultValue: "");

Demo

Demo使用您的数据集

  

score1列上的索引可能对您有所帮助