Créez un index multicolonne partiel avec cet ordre de tri particulier :
CREATE INDEX products_status_sales_partial_idx ON products (status, sales DESC)
WHERE category NOT IN ('cat3','cat7');
Modifiez légèrement votre requête :
SELECT product_no, sales
FROM products
WHERE status = 'something'
AND category NOT IN ('cat3', 'cat7')
ORDER BY status, sales DESC
LIMIT 3;
Ajout de status
comme premier élément du ORDER BY
clause semble redondante et inutile. Mais essayez-le.
Pourquoi ?
Le planificateur de requêtes n'est pas assez intelligent pour comprendre qu'avec
WHERE status = 'something' ...
ORDER BY sales DESC
l'ordre de tri de l'index (status, sales DESC)
correspond comme une conséquence logique. Donc, il va lire tous lignes de qualification, triez et choisissez les 3 premières.
En ajoutant status
au ORDER BY
vous autorisez le planificateur de requêtes à lire directement les 3 premières entrées de l'index. Attendez-vous à une accélération de plusieurs ordres de grandeur .
Testé avec PostgreSQL 8.4 et 9.1.