2016-01-16 5 views
1

У меня есть следующий SQL-запрос, но я заметил, что он оказывает некоторое давление на мой сервер, так как каждый раз, когда я его запускаю, загрузка процессора достигает 20%.Каков наилучший способ оптимизации этого запроса sql

SELECT 
    c.name, c.billingaddress, c.billingcity, c.billingstate, c.billingzip,c.ifActive, 
    (SELECT COUNT(l.id) FROM newLoads l WHERE l.idCompany = c.id AND l.smallStatus='1') as numberLoads, 
    (SELECT (SUM(l.loadRate))/(SUM(l.esMiles)) FROM newLoads l WHERE l.idCompany = c.id AND l.loadRate != '0' AND l.esMiles != '0' AND l.smallStatus='1') as RPM 
    FROM `companies` c WHERE ifContractor ='0' $cond 
    ORDER BY numberLoads DESC 

ответ

1

Это ваш запрос:

SELECT c.name, c.billingaddress, c.billingcity, c.billingstate, c.billingzip, c.ifActive, 
     (SELECT COUNT(l.id) 
     FROM newLoads l 
     WHERE l.idCompany = c.id AND l.smallStatus = '1' 
     ) as numberLoads, 
     (SELECT (SUM(l.loadRate))/(SUM(l.esMiles)) 
     FROM newLoads l 
     WHERE l.idCompany = c.id AND l.loadRate <> '0' AND l.esMiles <> '0' AND l.smallStatus = '1' 
     ) as RPM 
FROM `companies` c 
WHERE ifContractor = '0' $cond 
ORDER BY numberLoads DESC; 

Я не знаю, что $cond должно быть. Это, безусловно, недействительный синтаксис SQL, поэтому я проигнорирую его.

По этому запросу у вас есть следующие индексы: companies(ifContractor, id) и newload(idCompany, smallstatus, loadrate, esmiles, id).

Кстати, если столбцы, значения которых выглядят как числа, действительно являются числами, то оставьте одинарные кавычки. Преобразование типов может привести к запуску оптимизатора.

+0

Что такое <> для? –

+0

$ cond - переменная, содержащая условия, которые я установил перед запуском запроса –

+0

@RaTre. , , '<>' - обычный оператор, используемый для неравных в SQL. Условия в 'WHERE' могут повлиять на оптимизацию. –

2

Это мощь быть более эффективным:

SELECT c.name, c.billingaddress, c.billingcity, 
     c.billingstate, c.billingzip, c.ifActive, 
     x.numberLoads, x.RPM 
    FROM 
     (SELECT l.idCompany, 
       COUNT(*) AS numberLoads, 
       SUM(l.loadRate))/(SUM(l.esMiles) AS RPM 
      FROM newLoads l 
      WHERE l.smallStatus = '1' 
    ) AS x 
    JOIN companies AS c ON c.id = x.idCompany 
    WHERE ifContractor = '0' $cond 
    ORDER BY x.numberLoads DESC; 

Просьба SHOW CREATE TABLE и EXPLAIN SELECT ....

1

Возможно, 20% не так уж плохо? (особенно, если это только для короткого пакета). По его мнению, для получения результата может потребоваться множество данных.

Я попытался объединить скопления на столе newLoads в один SELECT и в итоге оказался чем-то (очень) похожим на то, что у Рика Джеймса уже было. Дополнительным преимуществом моей конструкции является то, что она больше соответствует исходному запросу в случае отсутствия соответствующей информации в newLoads и/или когда в одном из полей есть нуль. (Я думаю, на самом деле не проверить это)

SELECT c.name, c.billingaddress, c.billingcity, c.billingstate, c.billingzip, c.ifActive, agg.numberLoads, agg.RPM 
FROM `companies` c 
LEFT OUTER JOIN ((SELECT l.idCompany, 
          numberLoads = COUNT(l.id), 
          RPM = (CASE WHEN SUM((CASE WHEN l.loadRate <> '0' AND l.esMiles <> '0' THEN 1 ELSE 0 END)) = 0 THEN NULL ELSE 

            SUM((CASE WHEN l.loadRate <> '0' AND l.esMiles <> '0' THEN l.loadRate ELSE 0 END))/SUM((CASE WHEN l.loadRate <> '0' AND l.esMiles <> '0' THEN l.esMiles ELSE 0 END)) 
             END) 
        FROM newLoads l 
        WHERE l.smallStatus = '1' 
        ) AS agg 
      ON agg.idCompany = c.id 

WHERE c.ifContractor = '0' $cond 
ORDER BY agg.numberLoads DESC; 

Во всяком случае, если продолжительность является проблемой, вы можете проверить, если у вас есть (соединение) индексы на соответствующих областях, как Гордон Линофф по праву предложенных, и также о том, что может быть в $cond; вероятно, имеет смысл увидеть, какая фильтрация происходит там и какое влияние оно оказывает на общую производительность запроса.

PS: не имея много практический опыт работы с MySQL я задавался вопросом, если l.esMiles <> '0' не «медленнее», чем l.esMiles <> 0, в предположении, что l.esMiles является числовое поле (например, целым числом или десятичной и т.д ..)

Смежные вопросы