如何找出表中特定组中特定行的行号?

时间:2012-12-18 16:10:37

标签: mysql optimization row

考虑下表:

rowid   |   text    |   group
1       |   a       |   1
2       |   b       |   2
3       |   c       |   2
4       |   d       |   3
5       |   e       |   4
6       |   f       |   1
7       |   g       |   1
8       |   h       |   4
9       |   j       |   5
10      |   k       |   2
11      |   i       |   3
12      |   l       |   3

现在想象我想要行号rowid 6(用于例如分页)。由于它是自动递增的,所以选择where rowid = 6非常简单,但在这种情况下,我想知道它在第1组中的行号

显然,在这么小的例子(它的第2行)中,通过眼睛很容易做到这一点。

第1行是rowid = 1。 第2行是rowid = 6。 第3行是rowid = 7

我的第一个想法是这样的:

SELECT
    tmp.rowid,
    tmp.text,
    tmp.group,
    tmp.row_number
FROM
    (
        SELECT
            `rowid`,
            `text`,
            `group`,
            (@rowNumber := @rowNumber + 1) as `row_number`
        FROM
            `my_table`,
            (SELECT @rowNumber := 0) as `r`
        WHERE
            `group` = 1
        ORDER BY
            `rowid` DESC
    ) as `tmp`
WHERE
    tmp.rowid = 6

哪个会给出正确的结果(在row_number中),但在一张大桌子上(50万条记录),这将需要2.5秒才能在快速服务器上运行,因为它必须首先收集所有500,000个条目,然后选择行ID 6。

我应该怎么做才能更快/更好?

1 个答案:

答案 0 :(得分:1)

解决方案实际上非常简单。

SQL

SELECT
    COUNT(`rowid`) as `row_number`
FROM
    `my_table`
WHERE
    `group` = 1
AND
    `rowid` >= 6

您需要一个具有递增值的行(例如时间戳,递增ID等)。

我们将原始ORDER BY rowid DESC转换为WHERE rowid >= '6'。如果您使用ORDER BY升序,则需要使用<=

查询需要0.00002秒,并返回正确的行号(在row_number中)。如果您需要textgroup列,则必须将其设为子查询或进行选择WHERE rowid = 6的其他查询。