【问题标题】:mysql select from n last rowsmysql 从最后 n 行中选择
【发布时间】:2010-10-09 02:06:42
【问题描述】:

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

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

【问题讨论】:

    标签: mysql select query-optimization


    【解决方案1】:

    像使用分页一样利用 SORT 和 LIMIT。如果您想要第 i 个行块,请使用 OFFSET。

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

    回应尼尔: 排序操作不一定会受到惩罚,这取决于查询计划器的工作。由于这个用例对分页性能至关重要,因此有一些优化(见上面的链接)。这在 postgres 中也是如此“ORDER BY ... LIMIT 可以在不排序的情况下完成”E.7.1. Last bullet

    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,所以我完全删除了这个例子。
    • 在当前示例中,数据库引擎必须查看所有 n 行,即使它在第一行找到值。不太优化。
    • 在我的非严格测试中,mysql 5.0.x 使用索引,如上。
    【解决方案2】:

    从@chaos给出的answer开始,但做了一些修改:

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

    • 如果按降序排序,则不需要事先知道表格的行数。

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

    这是我的查询版本:

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

    【讨论】:

    • 如果可以的话,我会多次投票,所有其他答案都是错误的。这也是我会发布的。
    • 请注意,我提到的@chaos 的答案已被删除。
    • 谢谢!引擎需要扫描多少条记录才能得到答案?是n吗?还是 m= val 从顶部开始的位置?
    • 我认为它只需要扫描 n 行。 ORDER BY...LIMIT 可以使用索引完成,无需扫描行。
    • @JSHelp,OP 询问如何检查 某个数字 是否出现在最后 n 行中。所以$certain_number 是 OP 正在搜索的值。 $n 不是结果的大小,而是要搜索的行数。如果val 是唯一列,则结果的大小可能只有一,或者可能高达$n,或者如果找不到该值,则可能为零行。
    【解决方案3】:

    因为它是自动增量,所以这是我的看法:

    Select * from tbl 
    where certainconditionshere 
    and autoincfield >= (select max(autoincfield) from tbl) - $n
    

    【讨论】:

    • 我只想更改 WHERE 子句中的条件顺序。
    • 此答案假定最后 $n 行具有连续的 id 值。
    【解决方案4】:

    最后 5 行在 mysql 中检索

    此查询完美运行

    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
    

    【讨论】:

      【解决方案5】:

      我知道这可能有点旧,但请尝试使用PDO::lastInsertId。我认为它可以满足您的要求,但您必须重写您的应用程序才能使用 PDO(这对攻击更安全)

      【讨论】:

        【解决方案6】:

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

        select * from table_name order by id desc limit 5
        

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

        【讨论】:

        • 这提供了什么价值?这个问题在六年前就得到了回答。代码 sn-p 似乎是先前提供的答案的子集,它没有解释。
        猜你喜欢
        • 2012-08-20
        • 2014-02-28
        • 1970-01-01
        • 1970-01-01
        • 2014-11-27
        • 2012-02-07
        • 1970-01-01
        相关资源
        最近更新 更多