Crea un indice parziale a più colonne con questo particolare ordinamento:
CREATE INDEX products_status_sales_partial_idx ON products (status, sales DESC)
WHERE category NOT IN ('cat3','cat7');
Modifica leggermente la tua richiesta:
SELECT product_no, sales
FROM products
WHERE status = 'something'
AND category NOT IN ('cat3', 'cat7')
ORDER BY status, sales DESC
LIMIT 3;
Aggiunta di status
come primo elemento del ORDER BY
la clausola sembra ridondante e priva di senso. Ma provalo.
Perché?
Il pianificatore di query non è abbastanza intelligente da capire, che con
WHERE status = 'something' ...
ORDER BY sales DESC
l'ordinamento dell'indice (status, sales DESC)
corrisponde come logica conseguenza. Quindi leggerà tutto righe qualificanti, ordina e scegli le prime 3.
Aggiungendo status
al ORDER BY
consenti al pianificatore di query di leggere direttamente le prime 3 voci dall'indice. Aspettati un aumento di diversi ordini di grandezza .
Testato con PostgreSQL 8.4 e 9.1.