Ускорение SQL-запросов, которые вычисляют скорость - PullRequest
0 голосов
/ 07 мая 2018

Мне нужно вычислить коэффициент соответствия, а также сохранить общее количество доставок, все это для каждого оператора (транспортера) в 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.) Как я могу ускорить этот тип запроса (и, между прочим, упростить его) до нескольких секунд?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Я переработал ответ 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.

0 голосов
/ 07 мая 2018

Глядя на свой код, вы можете избежать выбора значений столбцов, используя подвыбор в соединении, например:

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, используя другое внутреннее объединение

...