Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Вопрос-Ответ Новый топик    Ответить
 Скорость выполнения запроса...  [new]
Sanych
Member

Откуда:
Сообщений: 10
Есть такой вот запрос:

SELECT Extensions.ExtensionNumber AS ExtensionName, COUNT( Calls.ID ) AS Quantity, SUM( Calls.Duration ) AS Duration, SUM( Calls.CallCost ) AS Cost
FROM Extensions
LEFT JOIN Calls ON (Calls.OriginationNumber=Extensions.ExtensionNumber OR Calls.DestinationNumber=Extensions.ExtensionNumber )
GROUP BY Extensions.ExtensionNumber ORDER BY Cost

Поля Calls.OriginationNumber, Calls.DestinationNumber и Extensions.ExtensionNumber индексированы.

В таблице Calls примерно 9000 записей.
В таблице Extensions - 40 записей.

Время выполнения такого запроса, у меня на машинке, примерно 13 секунд.
Если убрать одно из условий или поставить AND вместо OR в условии LEFT JOIN , время выполнения запроса будет меньше 0.5 секунды. Результат, конечно же будет неправильный.

Подскажите, пожалуйста, как ускорить время выполнения этого запроса.
30 окт 03, 19:43    [400643]     Ответить | Цитировать Сообщить модератору
 Re: Скорость выполнения запроса...  [new]
JibSkeart
Member

Откуда: Из далекой галактики
Сообщений: 19870
Постамить более крутую машину
Картинка с другого сайта.
31 окт 03, 17:11    [402153]     Ответить | Цитировать Сообщить модератору
 Re: Скорость выполнения запроса...  [new]
Ой Вэй
Member

Откуда: Харьков
Сообщений: 581
Sanych
Не слушай его, я тебе сейчас расскажу.
Я с удовольствием пронаблюдал описанный тобой эффект, только у меня обе таблицы большие.

Простой вариант работал больше минуты, а извращённый -- мгновенно.

Проблема в том, что надо ссылаться из одной таблицы Calls два раза в одну и ту же таблицу Extensions. Ну так сделаем две таблицы Extensions (запрос A):

SELECT Count(Calls2.ID) FROM

(Extensions AS Extensions1 LEFT JOIN Calls AS Calls1 ON Extensions1.ExtensionNumber=Calls1.OriginationNumber)
INNER JOIN
(Extensions AS Extensions2 LEFT JOIN Calls AS Calls2 ON
Extensions2.ExtensionNumber=Calls2.DestinationNumber)
ON Extensions1.ExtensionNumber=Extensions2.ExtensionNumber

GROUP BY Extensions1.ExtensionNumber, Extensions2.ExtensionNumber


(хочется надеяться, что поле Extensions.ExtensionNumber не только индексированное, но и уникальное)

Тут плохо то, что записи из Extensions1 и Extensions2 в пределах одного ExtensionNumber встречаются во всех комбинациях, т.е. количество записей равно произведению количеств записей в Calls с подходящими OriginationNumber и DestinationNumber, а нам надо эти количества просуммировать.
--------------------------------------

Пошли дальше, придётся добавить в GROUP BY ещё и Calls1.ID, а в SELECT поле Extensions1.ExtensionNumber (раз есть GROUP BY, придётся что-нибудь взять, годится Min()).

SELECT
Min(Extensions1.ExtensionNumber) AS ExtensionNumber1,
Count(Calls2.ID) AS CallsID2

FROM

(Extensions AS Extensions1 LEFT JOIN Calls AS Calls1 ON
Extensions1.ExtensionNumber=Calls1.OriginationNumber)
INNER JOIN
(Extensions AS Extensions2 LEFT JOIN Calls AS Calls2 ON
Extensions2.ExtensionNumber=Calls2.DestinationNumber)
ON Extensions1.ExtensionNumber=Extensions2.ExtensionNumber

GROUP BY Extensions1.ExtensionNumber, Extensions2.ExtensionNumber, Calls1.ID


А сверху на это навернуть ещё запрос A1:

SELECT ExtensionNumber1, Count(CallsID2)
FROM A
GROUP BY ExtensionNumber1


Напиши, пожалуйста, о результатах и какая DBMS. Я игрался на Access97.
31 окт 03, 20:43    [402408]     Ответить | Цитировать Сообщить модератору
 Re: Скорость выполнения запроса...  [new]
Ой Вэй
Member

Откуда: Харьков
Сообщений: 581
Извини, я недописал:

A1:

SELECT ExtensionNumber1, Min(CallsID2)+Count(CallsID2)
FROM A
GROUP BY ExtensionNumber1
1 ноя 03, 13:15    [402666]     Ответить | Цитировать Сообщить модератору
Все форумы / Вопрос-Ответ Ответить