Moja strona internetowa zawiera ponad 20 000 000 wpisów, wpisów ma kategorie (FK) i znaczniki (M2M). Jeśli chodzi o kwerendę nawet jak SELECT id FROM table ORDER BY id LIMIT 1000000, 10
MySQL musi skanować 1000010 wierszy, ale to jest naprawdę niedopuszczalnie powolne (i pks, indeksy, sprzężenia itp itp. Nie pomagają tutaj wiele, wciąż 1000010 wierszy). Więc staram się przyspieszyć paginacji przechowując liczbę wierszy i liczbę wierszy z wyzwalaczy, takich jak ten:Czy przechowywanie stronicowania i liczby wierszy do przechowywania stron jest złe?
DELIMITER //
CREATE TRIGGER @trigger_name
AFTER INSERT
ON entry_table FOR EACH ROW
BEGIN
UPDATE category_table SET row_count = (@rc := row_count + 1)
WHERE id = NEW.category_id;
NEW.row_number_in_category = @rc;
END //
A potem mogę po prostu:
SELECT *
FROM entry_table
WHERE row_number_in_category > 10
ORDER BY row_number_in_category
LIMIT 10
(teraz tylko 10 wierszy skanowana i dlatego wybiera się płonący szybko, chociaż wstawki są wolniejsze, ale są rzadkie w porównaniu do wybranych, więc jest w porządku)
Czy to złe podejście i czy istnieją dobre alternatywy?
Brzmi jak fajna optymalizacja; pod warunkiem, że wyeliminowałeś wszystkie inne przyczyny perfekcji (takie jak indeksy), ten rodzaj denormalizacji jest akceptowalny, ale rozważ przechowywanie tych informacji w osobnej tabeli metadanych, aby utrzymać główny schemat "czysty". – Dai
To dobry pomysł, ale prawdopodobnie nie jest to konieczne, ponieważ w odróżnieniu od Postgresql mysql obsługuje bardzo dobrze zliczanie (*) w tabelach indeksowanych. Zobacz moją odpowiedź tutaj, aby uzyskać więcej informacji http://stackoverflow.com/a/33006075/267540 – e4c5
Należy tylko przeskanować te wiersze, jeśli "id" nie jest indeksowany. Rozwiązujesz niewłaściwy problem. – EJP