考虑下表:
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。
我应该怎么做才能更快/更好?
答案 0 :(得分:1)
解决方案实际上非常简单。
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
中)。如果您需要text
和group
列,则必须将其设为子查询或进行选择WHERE rowid = 6
的其他查询。