Журнал коннектов к БД - средн. и макс. количество одновременных коннектов.
skorohod
Дата: 04.10.2005 15:51:11
FB 1.5.2
В БД есть таблица - журнал коннектов пользователей со след. структурой:
CREATE TABLE USER_LIST_ARCHIV (
USER_LIST_CURRENT_ID INT_ID NOT NULL /* INT_ID = INTEGER NOT NULL */,
LOGIN LOGIN_NAME NOT NULL /* LOGIN_NAME = VARCHAR(64) */,
CONNECT_NUMBER INT_ID NOT NULL /* INT_ID = INTEGER NOT NULL */,
PC_NAME STRING_64 NOT NULL COLLATE PXW_CYRL /* STRING_64 = VARCHAR(64) */,
APPLICATION_NAME STRING_32 NOT NULL COLLATE PXW_CYRL /* STRING_32 = VARCHAR(32) */,
DATE_CONNECT DATE_TIME_NOT_NULL_VALUE NOT NULL /* DATE_TIME_NOT_NULL_VALUE = TIMESTAMP DEFAULT current_timestamp NOT NULL */,
DATE_END DATE_TIME_VALUE /* DATE_TIME_VALUE = TIMESTAMP */,
FIRM_IDENT INT_TERRITORY NOT NULL /* INT_TERRITORY = INTEGER NOT NULL */
);
Т.е. БД используется разными приложениями одновременно кучей юзеров.
В таблице больше 100000 записей.
Нужно по этой табличке посчитать среднее и максимальное(пиковое) значение одновременно подключенных юзеров за все время "наблюдений". Не спрашивайте кому и зачем - ну вот надо!
Есть мысль связать таблицу саму на себя по условиям A.DATE_CONNECT >= B.DATE_CONNECT и A.DATE_CONNECT <= B.DATE_END (т.е. по каждой временной точке A.DATE_CONNECT проверяем всех, кто уже вошел но еще не вышел), результат сгруппировать по A.DATE_CONNECT и посчитать среднее и максимальное.
Только простое связывание - и select...select и select...join по таким условиям дает громадный результат, знач. нужно добавить первым ограничение join-а по Дата(A.DATE_CONNECT)=Дата(B.DATE_CONNECT) только вот как это сделать?! Как вытащить из поля TIMESTAMP значение DATE и сравнить его с таким же значением без учета временной составляющей?
Если есть альтернативные предложения - как ограничить join - буду признателен.
Если есть альтернативные предложения - как посчитать макс. и средн. - буду признателен вдвойне.
fraks
Дата: 04.10.2005 16:32:46
Я бы дума в след. сторону:
Сначала из лога надо получить последовательность событий коннекта и дисконнектав хронологическом порядке, типа так:
select DATE_CONNECT, 1
from log
UNION ALL
select DATE_END, -1
from log
order by 1
|
Этот запрос засунул бы в процедуру, и там бы подсчитывал текущее значение кол-ва коннектов.
create procedure test
returns(data timestamp, cnt integer)
as
declare variable v: integer;
begin
cnt = 0;
for select DATE_CONNECT, 1
from log
UNION ALL
select DATE_END, -1
from log
order by 1
into :data, :v do begin
cnt = cnt + :v:
suspend;
end
end
|
Ну и по результату этой процедуры уже можно делать запросы по поводу max, min и прочего...
Писал прямо из мозга (с) просьба не стрелять по синтаксису.
sag494
Дата: 04.10.2005 16:38:11
Привет,
skorohod |
Не спрашивайте кому и зачем - ну вот надо! ... Если есть альтернативные предложения - как посчитать макс. и средн. - буду признателен вдвойне. |
предложу лобовое решение, которое особо подходит для гоняния на копии рабочей базы (дабы своей монстровостью не уложить рабочий сервер).
имхо, имеет смысл анализировать только временные метки соответсвующие DATE_CONNECT и DATE_END.
Сделать хп такого вида:
create procedure xp
returns (
P_DATA timestamp,
P_COUNT integer)
as begin
for select distinct DATE_CONNECT
from USER_LIST_ARCHIV
union
select distinct DATE_END
from USER_LIST_ARCHIV
INTO :P_DATA
do
begin
i=0;
select count(*)
from USER_LIST_ARCHIV
where :P_DATA between DATE_CONNECT and DATE_END
into :P_COUNT;
suspend;
end
end |
и уже по селекту по этой хп вычислять max и avg.
Хорошо бы чтобы для between использовался индекс и внешний цикл for_select все же был бы ограничен какими-то рамками.
Юрий Носов
Дата: 04.10.2005 16:58:04
IMHO тут две совсем разные задачи.
А. Максимальное число одновременных коннектов.
1. Упорядочить по возрастанию моменты подключения и отключения.
2. Пройтись по этой таблице, каждое подключение считать с плюсом, отключение- с минусом. Максимальное значение и даст искомое.
Б. Среднее число коннектов.
1. Просуммировать время всех коннектов и поделить на общее время работы.
sag494
Дата: 04.10.2005 16:59:49
fraks |
select DATE_CONNECT, 1
from log
UNION ALL
select DATE_END, -1
from log
order by 1
| Этот запрос засунул бы в процедуру, и там бы подсчитывал текущее значение кол-ва коннектов. |
Красиво!
kdv
Дата: 04.10.2005 17:31:11
не совсем по вопросу, но все же. Вот типичный пример, почему я не люблю домены, и почему люди иногда перебарщивают с доменами:
DATE_CONNECT DATE_TIME_NOT_NULL_VALUE NOT NULL
/* DATE_TIME_NOT_NULL_VALUE = TIMESTAMP DEFAULT current_timestamp NOT NULL */
это ж вообще удолбаться можно. Домен невообразимого имени, с not null, да еще и столбцу not null сказан!
И все это вместо того чтобы написать
DATE_CONNECT TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL.
Причем, думаю, not null тут можно выкинуть.
skorohod
Дата: 04.10.2005 17:53:30
Спасибо ответившим за хелп.
Действительно красиво если применять в лоб "+1 и -1", только в этом случае реалии жизни демонстрируют наличие отрицательного количества коннектов :)
DateTime__Flag_Conn
23.04.2004 17:53 1 0
23.04.2004 17:54 -1 0
23.04.2004 18:12 1 0
23.04.2004 18:12 -1 0
23.04.2004 18:13 1 0
23.04.2004 18:14 -1 0
26.04.2004 00:00 -1 0
26.04.2004 00:00 -1 0
26.04.2004 00:00 -1 0
26.04.2004 00:00 -1 0
26.04.2004 00:00 -1 0
26.04.2004 00:00 -1 0
26.04.2004 00:00 -1 0
26.04.2004 00:00 -1 0
26.04.2004 00:00 -1 0
26.04.2004 00:00 -1 0
26.04.2004 00:00 -1 0
26.04.2004 09:27 1 0
26.04.2004 09:27 -1 0
26.04.2004 09:43 1 0
26.04.2004 09:44 -1 0
26.04.2004 09:45 1 0
26.04.2004 09:46 -1 0
Думаю без ограничения подсчета внутри каждой даты (начиная каждый день с 0 коннектов с 9.00) тут не обойтись!
skorohod
Дата: 04.10.2005 18:00:09
2 kdv
Сорри, база не моя - просто пришлось разбираться.
Скрипт по таблице сделал IBExpert а саму таблицу - авторы когда-то.
Второй нот нулл дал "крестик" в поле "не пусто" интерфейса IBE.
Конечно это дублирование информации в скрипте, но приводит ли это к двойной проверке каждой записи - я пока не в курсе - с FB только начинаю...
kdv
Дата: 04.10.2005 18:38:06
к двойной проверке ничего не приводит. просто у столбца есть характеристики, которые могут перекрывать характеристики домена. например у домена not null нет, а у столбца, базирующемся на этом домене not null можно включить. Похоже в БД not null забабахано в обоих местах.
fraks
Дата: 05.10.2005 05:44:17
skorohod |
Спасибо ответившим за хелп. Действительно красиво если применять в лоб "+1 и -1", только в этом случае реалии жизни демонстрируют наличие отрицательного количества коннектов :) Думаю без ограничения подсчета внутри каждой даты (начиная каждый день с 0 коннектов с 9.00) тут не обойтись! |
Сначала я бы отрезал все записи у которых
((date_start is NULL) or (date_end is NULL))
and (date_end < date_start) |