Ook al specificeert u LIMIT 100, voor dit type zoekopdracht moet een volledige scan en tabel worden opgebouwd, waarna elk record wordt geïnspecteerd en een rij wordt genummerd voordat uiteindelijk wordt gefilterd op de 100 die u wilt weergeven.
select
vendorid, productid, NumSales
from
(
select
vendorid, productid, NumSales,
@r := IF(@g=vendorid,@r+1,1) RowNum,
@g := vendorid
from (select @g:=null) initvars
CROSS JOIN
(
SELECT COUNT(oi.price) AS NumSales,
p.productid,
p.vendorid
FROM products p
INNER JOIN vendors v ON (p.vendorid = v.vendorid)
INNER JOIN orders_items oi ON (p.productid = oi.productid)
INNER JOIN orders o ON (oi.orderid = o.orderid)
WHERE (p.Approved = 1 AND p.Active = 1 AND p.Deleted = 0)
AND (v.Approved = 1 AND v.Active = 1 AND v.Deleted = 0)
AND o.`Status` = 'SETTLED'
AND o.Deleted = 0
GROUP BY p.vendorid, p.productid
ORDER BY p.vendorid, NumSales DESC
) T
) U
WHERE RowNum <= 3
ORDER BY NumSales DESC
LIMIT 100;
De aanpak hier is
- Groepeer op om NumSales te krijgen
- Gebruik variabelen om de verkopen per leverancier/product te nummeren
- Filter de genummerde dataset zodat er maximaal 3 per leverancier mogelijk zijn
- Bestel de rest bij NumSales DESC en retourneer slechts 100