Я должен вычислить коэффициент соответствия, а также сохранить общее количество доставок, все это для каждого оператора (транспортера) в SQL. Вот запрос, который я разработал, чтобы удовлетворить эту потребность, и он успешно справляется, но для его выполнения требуется около 5 минут (зная, что в таблице «LIVRAISON» содержится около 350 000 записей):
SELECT idTrans AS id,
nomTrans,
(COUNT(codeSt)
/ (SELECT COUNT(*)
FROM LIVRAISON
NATURAL JOIN TOURNEE
WHERE idTrans=id
AND DateTrn = DATE_SUB(SYSDATE(), INTERVAL 1 DAY)
)
) AS Taux,
(SELECT COUNT(*)
FROM LIVRAISON
NATURAL JOIN TOURNEE
WHERE idTrans=id
AND DateTrn = DATE_SUB(SYSDATE(), INTERVAL 1 DAY)
) AS Total
FROM LIVRAISON
NATURAL JOIN TOURNEE
NATURAL JOIN TRANSPORTEUR
WHERE "{status_type}"AND DateTrn = DATE_SUB(SYSDATE(), INTERVAL 1 DAY)
GROUP BY idTrans
(status_type
это условие IN, добавленное в PHP.)
Как я могу ускорить этот тип запроса (и, между прочим, упростить его) до нескольких секунд?
Глядя на ваш код, вы можете избежать выбора значений столбцов, используя подвыбор в соединении, например:
select DISTINCT LIVRAISON.idTrans AS id
, TRANSPORTEUR.nomTrans
, t.my_rate
, t.my_count
FROM LIVRAISON
NATURAL JOIN TOURNEE
NATURAL JOIN TRANSPORTEUR
INNER JOIN (
SELECT idTrans, COUNT(codeSt)/COUNT(*) my_rate, COUNT(*) my_count
FROM LIVRAISON
NATURAL JOIN TOURNEE
WHERE idTrans=id
AND DateTrn = DATE_SUB(SYSDATE(), INTERVAL 1 DAY)
GROUP BY idTrans ) t ON t.idTrans = LIVRAISON.idTrans
WHERE "{status_type}"AND DateTrn = DATE_SUB(SYSDATE(), INTERVAL 1 DAY)
может быть, вы также можете избежать предложения IN, используя другое внутреннее соединение
Я переработал ответ scaisEdge (который выполняется вовремя, но все значения равны 1), чтобы сделать его пригодным для использования:
SELECT TOURNEE.idTrans, nomTrans, ( t.tot_typeSt/COUNT(*) ) AS Taux,
COUNT(*) AS Total
FROM LIVRAISON NATURAL JOIN TOURNEE NATURAL JOIN TRANSPORTEUR
INNER JOIN ( SELECT TOURNEE.idTrans, COUNT(codeSt) AS tot_typeSt
FROM LIVRAISON NATURAL JOIN TOURNEE
WHERE {$typeStatut} AND DATE_SUB(SYSDATE(), INTERVAL 1 DAY)
GROUP BY TOURNEE.idTrans ) t ON t.idTrans = TOURNEE.idTrans WHERE DATE_SUB(SYSDATE(), INTERVAL 1 DAY)
GROUP BY idTrans
Спасибо, я буду помнить, используя INNER JOIN
для этого.