Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL在存在使用变量的索引时的排名_Mysql_Sql_Mariadb - Fatal编程技术网

MySQL在存在使用变量的索引时的排名

MySQL在存在使用变量的索引时的排名,mysql,sql,mariadb,Mysql,Sql,Mariadb,使用使用@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

使用使用@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中的一个bug吗?

这个“把戏”是一颗等待爆炸的炸弹。一个聪明的优化器会根据它认为合适的方式对查询进行评估,为速度进行优化——这就是为什么它被称为优化器。我不认为MySQL变量的这种使用是按照您预期的方式记录的,但它确实起了作用

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

您可以做的(直到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 ;
选择
将(*)计算为等级,
fa.id,
法瓦尔
从…起
表1作为fa
内连接表2作为em
在em.id=fa.id上
和em.type='A'
内连接
表1为fa2
内部连接表2作为em2
在em2.id=fa2.id上
和em2.type='A'
关于fa2.id