【问题标题】:MySQL ranking in presence of indexes using variablesMySQL使用变量在存在索引的情况下排名
【发布时间】:2012-06-07 01:33:12
【问题描述】:

使用@N=@N + 1 的经典技巧来获取某个有序列上项目的排名。现在在订购之前,我需要通过将基表与其他表进行内部连接来过滤掉基表中的一些值。所以查询看起来像这样 -:

SET @N=0;
SELECT 
  @N := @N + 1 AS rank,
  fa.id,
  fa.val 
FROM
    table1 AS fa 
    INNER JOIN table2 AS em 
      ON em.id = fa.id 
      AND em.type = "A" 
ORDER BY fa.val ;

问题是,如果我在 em.type 上没有索引,那么一切正常,但如果我在 em.type 上放置索引,那么地狱就会释放,排名值而不是按 val 列排序按行存储在 em 表中的顺序。

这里是示例输出 -:

没有索引-:

rank    id         val
1   05F8C7  55050.000000
2   05HJDG  51404.733458
3   05TK1Z  46972.008208
4   05F2TR  46900.000000
5   05F349  44433.412847
6   06C2BT  43750.000000
7   0012X3  42000.000000
8   05MMPK  39430.399658
9   05MLW5  39054.046383
10  062D20  35550.000000

带索引-:

rank      id        val
480     05F8C7  55050.000000
629     05HJDG  51404.733458
1603    05TK1Z  46972.008208
466     05F2TR  46900.000000
467     05F349  44433.412847
3534    06C2BT  43750.000000
15      0012X3  42000.000000
1109    05MMPK  39430.399658
1087    05MLW5  39054.046383
2544    062D20  35550.000000

我相信索引的使用应该是完全透明的,并且输出不应该受到它的影响。这是 MySQL 的错误吗?

【问题讨论】:

    标签: mysql sql mariadb


    【解决方案1】:

    这个“把戏”是一颗等待爆炸的炸弹。一个聪明的优化器会在它认为合适的时候评估一个查询,优化速度——这就是它被称为优化器的原因。我不认为这种 MySQL 变量的使用被证明可以像您期望的那样工作,但它确实有效。

    一直有效,直到最近对 MariaDB 优化器进行了改进。它可能也会在主流 MySQL 中崩溃,因为在(尚未发布,仍是 beta)5.6 版本中优化器有几处改进。

    您可以做的(直到 MySQL 实现窗口函数)是使用自连接和分组。无论优化器未来做了什么改进,结果都是一致的。缺点是它可能不是很有效:

    SELECT 
      COUNT(*) AS rank,
      fa.id,
      fa.val 
    FROM
        table1 AS fa 
        INNER JOIN table2 AS em 
          ON em.id = fa.id 
          AND em.type = 'A'
    
        INNER JOIN
    
        table1 AS fa2 
        INNER JOIN table2 AS em2 
          ON em2.id = fa2.id 
          AND em2.type = 'A' 
    
          ON fa2.id <= fa.id 
                              --- assuming that `id` is the Primary Key of the table
    GROUP BY fa.id
    ORDER BY fa.val ;
    

    【讨论】:

      猜你喜欢
      • 2023-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2011-02-27
      相关资源
      最近更新 更多