LIMIT 100を指定した場合でも、このタイプのクエリでは、フルスキャンとテーブルを作成し、すべてのレコードを検査して行番号を付けてから、表示する100を最終的にフィルタリングする必要があります。
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;
ここでのアプローチは
です- NumSalesを取得するためにグループ化する
- 変数を使用して、ベンダー/製品ごとの売上を行番号付けします
- 番号付きデータセットをフィルタリングして、ベンダーごとに最大3つを許可します
- 残りをNumSalesDESCで注文し、100個のみを返品します