2017-09-04 1 views
0

Je vais avoir quelques problèmes avec une requête qui trouve la prochaine ID d'un ordre avec certains filtres sur elle - comme il devrait être d'une ville spécifique, etc.PHP - optimisation SQL min/max trop lent

Actuellement, il est utilisé pour une fonction, où il va soit cracher l'ID précédent ou l'ID suivant en fonction de l'ordre actuel. Il peut donc être soit min (id) ou max (id), où max (id) est évidemment plus rapide, car il doit passer par moins de lignes.

La requête fonctionne très bien, mais il est plutôt lent, car il est en passant par 123953 lignes pour trouver l'ID. Y a-t-il un moyen de l'optimiser?

Exemple de fonction:

SELECT $minmax(orders.orders_id) AS new_id FROM orders LEFT JOIN orders_status ON orders.orders_status = orders_status.orders_status_id $where_join WHERE orders_status.language_id = '$languages_id' AND orders.orders_date_finished != '1900-01-01 00:00:00' AND orders.orders_id $largersmaller $ordersid $where; 

exemple en direct

SELECT min(orders.orders_id) 
FROM orders 
LEFT JOIN orders_status ON orders.orders_status = orders_status.orders_status_id 
WHERE orders_status.language_id = '4' 
    AND orders.orders_date_finished != '1900-01-01 00:00:00' 
    AND orders.orders_id < 4868771 
LIMIT 1 
+1

ont un indice sur orders.orders_id et supprimer les joints à orders_products et produits. Vous n'utilisez pas ces deux tables de toute façon. La clause where transforme votre jointure gauche en orders_status en une jointure interne, btw. – fancyPants

+0

est date_finished une clé? Et comment cette date peut-elle être 1900-01-01? À moins que vous travaillez sur des données historiques, ne serait pas NULL une valeur plus logique (comme je suppose que c'est ce que 1900 est à peu près) –

+0

@IvoP Il est un ancien système -real- et plein de défauts - Par conséquent pourquoi il est pas tout à fait logique ou optimal – Dandersen

Répondre

0

concluant ainsi:

SELECT orders.orders_id 
FROM orders 
JOIN orders_status ON orders.orders_status = orders_status.orders_status_id 
WHERE orders_status.language_id = '4' 
    AND orders.orders_date_finished != '1900-01-01 00:00:00' 
    AND orders.orders_id < 4868771 
ORDER BY orders.orders_id ASC 
LIMIT 1 

supplémentaire:

pour obtenir la valeur MAX, l'utilisation DESC où ASC est à présent.

Et regardant votre question: assurez-vous d'échapper aux valeurs telles que $ language_id etcetera. Je suppose qu'ils pourraient venir d'une forme html? (ou utiliser les commandes préparées)