Disponible
← Retour au journal
Modules

Compter les commandes par statut sans charger toutes les Order

Le piège classique : `Order::getOrders()` puis `count()`. Sur 100k commandes, c'est plusieurs secondes. Faites-le en SQL.

22.01.2026 ·Jérôme Admin

Le piège classique sur les dashboards custom : on veut afficher "12 commandes en attente, 47 livrées, 3 retours" et on écrit ça :

// ❌ À ne PAS faire sur 100k+ commandes
$orders = Order::getOrders();
$counts = [];
foreach ($orders as $o) {
    $counts[$o['current_state']] = ($counts[$o['current_state']] ?? 0) + 1;
}

Sur 100 000 commandes, ce code charge 100 000 lignes complètes en mémoire pour ne lire qu'une colonne. Comptez 4-6 secondes et 200 Mo de RAM.

La version SQL pure

$sql = '
    SELECT current_state, COUNT(*) as nb
    FROM ' . _DB_PREFIX_ . 'orders
    WHERE date_add >= DATE_SUB(NOW(), INTERVAL 30 DAY)
    GROUP BY current_state
';
$rows = Db::getInstance()->executeS($sql);

$counts = [];
foreach ($rows as $r) {
    $counts[(int) $r['current_state']] = (int) $r['nb'];
}

Mêmes 100 000 commandes : 40 ms, 0,5 Mo de RAM.

Avec libellés des statuts

$idLang = (int) $context->language->id;
$sql = '
    SELECT o.current_state, COUNT(*) as nb, osl.name
    FROM ' . _DB_PREFIX_ . 'orders o
    INNER JOIN ' . _DB_PREFIX_ . 'order_state_lang osl
      ON osl.id_order_state = o.current_state
     AND osl.id_lang = ' . $idLang . '
    WHERE o.date_add >= DATE_SUB(NOW(), INTERVAL 30 DAY)
    GROUP BY o.current_state, osl.name
    ORDER BY nb DESC
';

Cas plus large : agrégation multi-dimension

Pour des statistiques croisées (par statut + par mois), GROUP BY multiple :

SELECT
    DATE_FORMAT(date_add, '%Y-%m') AS mois,
    current_state,
    COUNT(*) AS nb,
    SUM(total_paid_tax_incl) AS ca
FROM ps_orders
WHERE date_add >= '2026-01-01'
GROUP BY mois, current_state
ORDER BY mois DESC, nb DESC;

Index utile pour ce type de requête : (date_add, current_state) — déjà présent par défaut sur PS 1.7+.

Règle générale : dès que vous itérez sur plus de 1000 ObjectModel pour faire un calcul, demandez-vous si une requête SQL ne ferait pas le boulot 100× plus vite.

#prestashop #mariadb #snippet #sql