2009-02-21 128 views
61

我有一個包含索引(autoincrement)和整數值的表。該表是數百萬行。mysql從最後n行中選擇

如何搜索某個數字是否最有效地出現在表的最後n行?

回答

87

從@chaos給出的answer開始 「ORDER BY ... LIMIT可以不選做」,但有一些修改:

  • 如果您使用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; 
12

您可以像分頁一樣利用SORT和LIMIT。如果你想要第i行的塊,使用OFFSET。

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

針對尼爾: 排序操作不一定受到處罰,這取決於查詢規劃做什麼。由於此用例對分頁性能至關重要,因此有一些優化(請參閱上面的鏈接)。這是在Postgres裏也是如此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 | 
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+ 
+0

不能使用MAX()或COUNT()插入您已經。 – 2009-02-22 01:53:42

+0

用CASE語句替換了不正確的代碼。 – 2009-02-22 07:22:08

+0

大小寫沒有去掉NULL,所以我完全刪除了這個例子。 – 2009-02-22 07:30:55

3

,因爲它是自動增量,這是我的看法:

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

最後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 
0

我知道這可能是有點老了,但請嘗試使用PDO::lastInsertId。我認爲它你希望它是什麼,但你將不得不重寫你的應用程序中使用PDO(這是針對攻擊安全很多)

14

可能是很晚的答案,但是這是很好的,簡單的。

select * from table_name order by id desc limit 5 

這個查詢將返回一組最後5個值(最後5行)的WHERE子句中的表