【发布时间】:2010-10-09 02:06:42
【问题描述】:
我有一个带有索引(自动增量)和整数值的表。该表有数百万行长。
如何最有效地搜索某个数字是否出现在表格的最后n行?
【问题讨论】:
标签: mysql select query-optimization
我有一个带有索引(自动增量)和整数值的表。该表有数百万行长。
如何最有效地搜索某个数字是否出现在表格的最后n行?
【问题讨论】:
标签: mysql select query-optimization
像使用分页一样利用 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 |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
【讨论】:
从@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;
【讨论】:
$certain_number 是 OP 正在搜索的值。 $n 不是结果的大小,而是要搜索的行数。如果val 是唯一列,则结果的大小可能只有一,或者可能高达$n,或者如果找不到该值,则可能为零行。
因为它是自动增量,所以这是我的看法:
Select * from tbl
where certainconditionshere
and autoincfield >= (select max(autoincfield) from tbl) - $n
【讨论】:
最后 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
【讨论】:
我知道这可能有点旧,但请尝试使用PDO::lastInsertId。我认为它可以满足您的要求,但您必须重写您的应用程序才能使用 PDO(这对攻击更安全)
【讨论】:
可能是一个很晚的答案,但这很好也很简单。
select * from table_name order by id desc limit 5
此查询将返回您在表中插入的一组最后 5 个值(最后 5 行)
【讨论】: