Il mio sito Web ha più di 20.000.000 di voci, le voci hanno categorie (FK) e tag (M2M). Per quanto riguarda la query, come SELECT id FROM table ORDER BY id LIMIT 1000000, 10
, MySQL ha bisogno di scansionare 1000010 righe, ma questo è davvero inaccettabilmente lento (e pks, indici, join ecc. Ecc. Non aiutano molto qui, ancora 1000010 righe). Così sto cercando di accelerare l'impaginazione memorizzando conteggio delle righe e il numero di riga con i trigger come questo:È una cattiva idea conservare il conteggio delle righe e il numero di righe per accelerare l'impaginazione?
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 //
e poi posso semplicemente:
SELECT *
FROM entry_table
WHERE row_number_in_category > 10
ORDER BY row_number_in_category
LIMIT 10
(ora solo 10 righe scansionato e quindi seleziona sono fiammeggiante veloce, anche se gli inserti sono più lenti, ma sono rari rispetto a selezionare, quindi è ok)
È un approccio cattivo e ci sono buone alternative?
Mi sembra un'ottimale ottimizzazione; ammesso che tu abbia eliminato tutte le altre cause perf (come gli indici) questo tipo di denormalizzazione è accettabile, anche se consideri di archiviare queste informazioni in una tabella di metadati separata per mantenere "pulito" lo schema principale. – Dai
È una buona idea, ma probabilmente non è necessaria perché, diversamente da Postgresql, mysql gestisce molto bene il conteggio (*) sulle tabelle indicizzate. Vedere la mia risposta qui per maggiori dettagli http://stackoverflow.com/a/33006075/267540 – e4c5
Basta scansionare quelle righe se 'id' non è indicizzato. Stai risolvendo il problema sbagliato. – EJP