2014-11-13 3 views
2

У меня есть таблица вроде этого:Оптимизация расчета процентов SQL запросы

------------------ 
sl no | Error type 
------------------ 
1  | err1 
------------------ 
2  | err2 
------------------ 
3  | err1 
------------------ 
4  | err2 
------------------ 
5  | err2 
------------------ 
6  | err3 
------------------ 

Результата Я хочу:

--------------------------- 
Error type | Count | % 
--------------------------- 
err1  | 2  | 33.33 
--------------------------- 
err2  | 3  | 50 
--------------------------- 
err3  | 1  | 16.66 
--------------------------- 

Я использую следующий запрос, чтобы получить выше результата:

select 
    error as Error, 
    count(*) as Count, 
    100* count(*)/(select count(*) from logs) as Percentage 
from logs 
group by error; 

Оптимизирован ли он для задачи? Если нет, то какие другие эффективные способы получить эту информацию?

+0

Вы считаете, что ваш вопрос 'select count (*) из подзапроса logs'? Или у вас есть еще одна проблема? –

+0

Это работает достаточно быстро для вас? Не беспокойтесь об эффективности, если это не станет проблемой. –

+0

@MichaelPetito Да – Abhijeet

ответ

2

Этот запрос будет выполнять count(*) в строке. Я бы запросить его один раз, и перекрестное соединение его отдельных подсчетов:

SELECT  a.error, a.cnt, 100 * a.cnt/b.total_count AS percentage 
FROM  (SELECT error, COUNT(*) as cnt 
      FROM  logs 
      GROUP BY error) a 
CROSS JOIN (SELECT COUNT(*) AS total_count FROM logs) b 
+0

Это неверно, поскольку 'count (*)' не будет выполняться один раз за строку в исходный запрос, который будет оптимизирован в плане выполнения. –

0

Не знаете, какую СУБД вы используете. Если ваша СУБД позволяет использовать агрегатные функции в качестве оконных функций (вы можете сделать это в Oracle), то вы можете сделать следующее:

SELECT error, COUNT(*) AS count, 100*COUNT(*)/COUNT(*) OVER () AS percentage 
    FROM logs 
GROUP BY error 

(Обратите внимание, что НАД() пункт пуст, чтобы указать, что общие подсчет - это то, что нужно.)

Надеюсь, это поможет.

+0

Я использую сервер mysql. :( – Abhijeet

+0

Пожалуйста, постарайтесь соответствующим образом пометить свои вопросы в будущем ... всегда помогает другим узнать, какую СУБД вы используете! –

0

Перед тем, как пойти и попытаться оптимизировать любой запрос, вы должны пересмотреть план выполнения. Например, в MSSQL, план запроса будет выглядеть следующим образом:

Query Plan

Вы можете очень четко увидеть два индекса сканирования (верхние и нижние ветви справа от «вложенных циклов»). Верхняя ветвь выполняет ваш агрегат count(*), чтобы получить общее количество строк в таблице. Это делается один раз, и итоговая одиночная строка, содержащая счет, соединяется с каждой из строк в нижней ветке. Нижняя ветвь выполняет совокупность count для каждой группы.

Таким образом, без изменения вашего высоко читаемого запроса у вас, вероятно, уже есть эффективный план выполнения.

+0

Спасибо, что указали это. Я был под впечатлением, что «подсчет count (*) из журналов будет выполняться для каждой строки во внешней таблице. – Abhijeet

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