2009-09-10 11 views
0

Короче у меня есть 2 таблицы:Лучший способ подсчета этого данные

ПОЛЬЗОВАТЕЛЕЙ:

------------------------ 
UserID | Name 
------------------------ 
0  a 
1  b 
2  c 

CALLS: 
------------------------ 
ToUser | Result 
------------------------ 
0  ANSWERED 
1  ENGAGED 
1  ANSWERED 
0  ANSWERED 

Etc и т.д. (я использовать числовую Referance результата в реальности)

У меня есть более 2 миллиона записей, каждый из которых указывает вызов конкретному клиенту. В настоящее время я использую заявление Case для подсчета каждого recurance конкретного результата после того как я уже сделал быстрый общий счет:

COUNT(DISTINCT l_call_log.line_id), 
COALESCE (SUM(CASE WHEN l_call_log.line_result = 1 THEN 1 ELSE NULL END), 0) AS [Answered], 
COALESCE (SUM(CASE WHEN l_call_log.line_result = 2 THEN 1 ELSE NULL END), 0) AS [Engaged], 
COALESCE (SUM(CASE WHEN l_call_log.line_result = 4 THEN 1 ELSE NULL END), 0) AS [Unanswered] 

я делаю 3 сканы данных после моего щётка общего количества? если да, то есть ли способ, которым я могу сделать одну развертку и считать вызовы как за один результат за один раз?

Спасибо.

ответ

0

Это займет одно полное сканирование таблицы.

EDIT: ответа недостаточно. потому что дублирование удаления (DISTINCT), которое я пропустил раньше, мы не можем сказать, какую стратегию использовать ... особенно, не зная механизм базы данных.

В каждом главном механизме запросов каждая агрегатная функция выполняется для каждого столбца для каждой строки и может использовать кешированный результат (например, COUNT (*)).

Связано ли с индексом line_result? Если это так, вы можете использовать лучший запрос (GROUP BY + COUNT (*), чтобы воспользоваться статистикой индексов, хотя я не уверен, что это стоит в зависимости от ваших других таблиц в запросе.

+0

Я попытался сделать индекс функции для результата, но он не отличался от IDE - он все еще Время, затрачиваемое на изучение, требует одного сканирования для завершения всех трех выражений. думая об этом, проведет ли он одно сканирование, чтобы сгруппировать вызовы через пользователя (подсчет числа), а затем другое сканирование для каждого пользователя для подсчета результатов? –

+0

Drat. Я пропустил часть вашего запроса DISTINCT, что меняет ситуацию. –

+0

Спасибо, в любом случае, Алекс, я думаю, ты поставил меня на правильный путь или, по крайней мере, правильно подумал, чтобы улучшить это. –

0

В SQL имеется конструкция GROUP BY. Попытайтесь:

SELECT COUNT(DISTINCT l_call_log.line_id) 
    GROUP BY l_call_log.line_result 
+0

да, я использую группу по стандарту. В этом случае я группируюсь по USERID, моя итоговая таблица по существу user | totalcount | answercount | involvedcount | unansweredcount –

0

Я бы предположил, что это сканирование таблицы, так как у вас нет каких-либо зависимых подзапросов. Запустите объяснение по запросу, чтобы быть уверенным.