MySQL从n最后一行选择


67

我有一个带有索引(自动递增)和整数值的表。该表长数百万行。

如何搜索某个数字是否最有效地出现在表格的最后n行中?

Answers:


94

从@chaos给出的答案开始,但进行了一些修改:

  • ORDER BY如果使用,则应始终使用LIMIT。对于RDBMS表,没有保证的隐式顺序。通常,您可能按主键的顺序获得行,但是您不能依靠它,也不是可移植的。

  • 如果按降序排列,则无需事先知道表中的行数。

  • 您必须为派生表指定一个相关名称(又名表别名)。

这是我的查询版本:

SELECT `id`
FROM (
    SELECT `id`, `val`
    FROM `big_table`
    ORDER BY `id` DESC
    LIMIT $n
) AS t
WHERE t.`val` = $certain_number;

1
如果可以的话,我会多次投票,其他所有答案都是错误的。这也是我要发布的内容。
Ray Hidayat

3
请注意,我引用的@chaos中的答案已删除。
比尔·卡文

谢谢!引擎必须扫描多少记录才能获得答案?是n吗?还是m = val从顶部开始的位置?
尼尔

我认为它只需要扫描n行。可以使用索引完成ORDER BY ... LIMIT,而无需扫描行。
比尔·卡文

1
@ JSHelp,OP询问如何检查最后n行中是否出现某个数字。所以就是OP正在搜索的价值。不是结果的大小,而是要搜索的行数。结果的大小可能只有一个(如果是唯一列),或者最多为,或者如果找不到该值则可能为零行。$certain_number$nval$n
Bill Karwin 2014年

20

可能是一个很晚的答案,但这很简单。

select * from table_name order by id desc limit 5

该查询将返回您在表中插入的一组后5个值(后5行)


3
这提供了什么价值?六年前回答了这个问题。该代码段似乎是先前提供的答案的子集,并且没有解释。
jww 2014年

14

在mysql中检索最后5行

此查询工作正常

SELECT * FROM (SELECT * FROM recharge ORDER BY sno DESC LIMIT 5)sub ORDER BY sno ASC

要么

select sno from(select sno from recharge order by sno desc limit 5) as t where t.sno order by t.sno asc

12

与分页一样,充分利用SORT和LIMIT的优势。如果要第i行,请使用OFFSET。

SELECT val FROM big_table
where val = someval
ORDER BY id DESC
LIMIT n;

针对Nir的响应:排序操作不一定要受到惩罚,这取决于查询计划程序的工作。由于此用例对分页性能至关重要,因此需要进行一些优化(请参见上面的链接)。在postgres中也是如此,“无需排序即可完成ORDER BY ... LIMIT” E.7.1。最后一颗子弹

explain extended select id from items where val = 48 order by id desc limit 10;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
|  1 | SIMPLE      | items | const | PRIMARY       | PRIMARY | 4       | const |    1 | Using index | 
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+

您不能在WHERE子句中使用MAX()或COUNT()。
比尔·卡文

Case不会去除NULL,所以我完全删除了该示例。
Dana the Sane,

在当前示例中,即使db引擎找到了第一个值,它也将不得不浏览所有n行。不太乐观。
尼尔

在我的非严格测试中,mysql 5.0.x使用一个索引,如上所述。
Dana the Sane,


0

我知道这可能有点老,但是请尝试使用PDO::lastInsertId。我认为它可以实现您想要的功能,但是您必须重写您的应用程序才能使用PDO(这样可以更安全地抵御攻击)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.