2009-02-21 10 views
61

Mam tabelę z indeksem (autoinkrement) i wartością całkowitą. Tabela ma miliony rzędów.mysql wybierz z ostatnich wierszy

Jak mogę wyszukać, czy dany numer pojawia się w ostatnich n wierszach tabeli najskuteczniej?

Odpowiedz

87

Począwszy od answer podanej przez @chaos, ale z kilkoma modyfikacjami:

  • Powinieneś zawsze używać ORDER BY, jeśli używasz LIMIT. Nie ma domyślnej kolejności gwarantowanej dla tabeli RDBMS. Możesz zwykle uzyskać wiersze w kolejności klucza podstawowego, ale nie można na nich polegać, ani nie jest ono przenośne.

  • Jeśli złożysz zamówienie w porządku malejącym, nie musisz wcześniej znać liczby wierszy w tabeli.

  • Należy podać nazwę korelacji (alias tabeli) do wyprowadzonej tabeli.

Oto moja wersja zapytania:

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

Chciałbym powtórzyć to kilka razy, gdybym mógł, wszystkie inne odpowiedzi są błędne. To też bym opublikował. –

+3

Zauważ, że odpowiedź z @chaos, do której się odwołuję, została usunięta. –

+0

Dzięki! Ile rekordów będzie musiał skanować silnik, aby uzyskać odpowiedź? Czy to jest n? lub m = położenie val od góry? – Nir

12

Skorzystaj z SORTOWANIA i LIMITU, jak w przypadku paginacji. Jeśli chcesz I-rzędowy blok wierszy, użyj PRZESUNIĘCIE.

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

W odpowiedzi na Nir: Operacja sortowania niekoniecznie jest karane, to zależy od tego, co robi Planowanie zapytania. Ponieważ ten przypadek użycia ma kluczowe znaczenie dla wydajności stronicowania, istnieją pewne optymalizacje (patrz link powyżej). Jest to prawdą w PostgreSQL, jak również "ORDER BY ... LIMIT można zrobić bez sortowania" 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

Nie można użyć max() lub COUNT() w klauzuli WHERE. –

+0

Zastąpiono niepoprawny kod instrukcją CASE. –

+0

Sprawa nie usuwa NULL, więc usunąłem ten przykład w całości. –

3

ponieważ jest autoincrement, oto moje zdanie:

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

Po prostu zmieniłbym kolejność warunków w klauzuli WHERE. –

+4

Ta odpowiedź zakłada, że ​​ostatnie wiersze $ n mają ciągłe wartości id. –

12

Ostatnie 5 rzędy odzyskać w mysql

Ten roboczego zapytania idealnie

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

lub

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

Najlepsze zapytanie działa doskonale w MySQL. Dzięki! – L0j1k

0

wiem, może to być nieco stary, ale spróbuj użyć PDO::lastInsertId. Myślę, że robi to, co chcesz, ale będziesz musiał przepisać swoją aplikację, aby użyć PDO (która jest o wiele bezpieczniejsza od ataków).

14

Może to być odpowiedź bardzo spóźniona, ale jest to dobre i proste.

select * from table_name order by id desc limit 5 

To zapytanie zwróci zestaw ostatnich 5 wartości (ostatnie 5 rzędów) ty „ve włożony w tabeli

+3

Jaką wartość to zapewnia? Odpowiedź na to pytanie została udzielona sześć lat temu. Fragment kodu wydaje się być podzbiorem wcześniej udzielonych odpowiedzi i nie zawiera objaśnień. – jww

+1

@jww dla OP, to jest poprawna odpowiedź –

+0

świetna, prosta i na temat! +1 – gumuruh