Страница 1 из 2
Чат на FB1.5
Добавлено: 25 окт 2005, 12:05
avenger
Здравствуйте уважаемые жители данного форума!
Пишу чат. Как правило в чате 100 человек.
Есть БД со следующей структурой:
Код: Выделить всё
CREATE TABLE MESSAGES (
MESSAGEID NUMERIC180 NOT NULL,
DATETIME INTEGER NOT NULL,
USERFK NUMERIC180 NOT NULL,
"MESSAGE" VARCHAR(5000) NOT NULL,
REPLYMID NUMERIC180,
STATUS SMALLINT NOT NULL
);
CREATE TABLE ONLINE (
USERFK NUMERIC180 NOT NULL,
LASTTIMEREFRESH INTEGER NOT NULL
);
CREATE TABLE USERS (
USERID NUMERIC180 NOT NULL,
);
ALTER TABLE MESSAGES ADD CHECK (STATUS IN (0,1,2));
ALTER TABLE MESSAGES ADD PRIMARY KEY (MESSAGEID);
ALTER TABLE ONLINE ADD PRIMARY KEY (USERFK);
ALTER TABLE USERS ADD PRIMARY KEY (USERID);
ALTER TABLE MESSAGES ADD FOREIGN KEY (USERFK) REFERENCES USERS (USERID) ON DELETE CASCADE;
ALTER TABLE MESSAGES ADD FOREIGN KEY (REPLYMID) REFERENCES MESSAGES (MESSAGEID) ON DELETE CASCADE;
ALTER TABLE ONLINE ADD FOREIGN KEY (USERFK) REFERENCES USERS (USERID) ON DELETE CASCADE;
CREATE INDEX IDX_MESSAGES1 ON MESSAGES (USERFK);
CREATE INDEX IDX_MESSAGES2 ON MESSAGES (REPLYMID);
CREATE UNIQUE INDEX IDX_MESSAGES3 ON MESSAGES (MESSAGEID);
CREATE INDEX IDX_ONLINE1 ON ONLINE (USERFK);
CREATE UNIQUE INDEX IDX_USERS1 ON USERS (USERID);
В основном работа идет с таблицей MESSAGES.
Какие параметры, операции вы посоветуете. Т.е. к примеру надо ли после inserta в таблицу Messages перещитывать статистику для индексов, может есть индексы которые лишние, и.т.д.
Можно ли соптимизировать следующий запрос:
Код: Выделить всё
SELECT U.FIO, U.ISVIP, M.* FROM USERS U, MESSAGES M
WHERE (U.USERID=M.USERFK AND MESSAGEID>$lastmsg)
ORDER BY M.DATETIME
Этот запрос выполняется у пользователя каждые 5 секунд. Если 100 пользователей, то запрос выполнится примерно 100 раз за 5 секунд.
Может быть можно держать часть данных в памяти?
Вообщем нужны советы.
P.S. Пожалуйста отнеситесь к данному вопросу серьезно.
С уважением Иван.
Добавлено: 25 окт 2005, 12:11
Ivan_Pisarevsky
Этот запрос выполняется у пользователя каждые 5 секунд.
Что мешает пользовать ивенты?
Может быть можно держать часть данных в памяти?
Кеш буфер ФБ+плюс правильное индексирование. Вполне достаточно будет, на мой взгляд.
Добавлено: 25 окт 2005, 12:12
Ivan_Pisarevsky
Стоп!!!
Это что за нумерик180???
Бр...
Добавлено: 25 окт 2005, 12:13
avenger
Что мешает пользовать ивенты?
Что такое ивенты?
Добавлено: 25 окт 2005, 12:14
avenger
Ivan_Pisarevsky писал(а):Стоп!!!
Это что за нумерик180???
Бр...
нумерик180 = NUMERIC(18,0)
Добавлено: 25 окт 2005, 12:18
avenger
Ivan_Pisarevsky писал(а):
Кеш буфер ФБ+плюс правильное индексирование. Вполне достаточно будет, на мой взгляд.
Кеш буфер ФБ можно как нибудь настроить? Может посоветуешь?
Добавлено: 25 окт 2005, 12:24
Ivan_Pisarevsky
1. ртфм, контескт 'events'
www.ibase.ru
2. читаем про скорость обработки integer, int64, numeric... для ключей нафиг не нужен нумерик, обычно интегер 32 бита, если планируется полее 4 миллиардов записей, то пользовать 64 битный ключ.
3. ртфм, контекст 'generator'
www.ibase.ru
4. Не стоит называть поле 'DATETIME' или что-то в этом духе, уж больно всякие зарезервированые слова напоминает, а для дат пользовать тип даных timestamp.
Добавлено: 25 окт 2005, 12:32
avenger
Ivan_Pisarevsky писал(а):1. ртфм, контескт 'events'
www.ibase.ru
2. читаем про скорость обработки integer, int64, numeric... для ключей нафиг не нужен нумерик, обычно интегер 32 бита, если планируется полее 4 миллиардов записей, то пользовать 64 битный ключ.
3. ртфм, контекст 'generator'
www.ibase.ru
4. Не стоит называть поле 'DATETIME' или что-то в этом духе, уж больно всякие зарезервированые слова напоминает, а для дат пользовать тип даных timestamp.
Насчет Numeric и integer ясно.
У меня есть 2-а генератора(users, messages) и соответственно при инсерте в таблицу срабатывает событие. А для чего еще ты предлагаешь использовать события?
Обновление статистики нужно после каждого inserta или раз в 100 инсертов например ?
Добавлено: 25 окт 2005, 12:37
kdv
да не нужно обновление статистики. ты еще запросы не написал, а уже о статистике по индексам бепокоишься?
Тем более, что слышал звон, и не знаешь где он - по первичным ключам обновлять статистику не имеет смысла. потому что они УНИКАЛЬНЫЕ. Статистику, обычно, если и обновляют, то по неуникальным индексам.
Скачай IBAnalyst, он тебе скажет, когда ее обновить, и даже даст по правой кнопке одним нажатием это сделать.
Добавлено: 25 окт 2005, 12:43
avenger
kdv писал(а): ты еще запросы не написал
Запросы написаны:
Когда пользователь написал сообщение:
Код: Выделить всё
$db->Execute("INSERT INTO MESSAGES (DATETIME, USERFK, "MESSAGE", REPLYMID, STATUS)
VALUES ($addtime, $UserID, '$Message', $ReplyMID, $Status)") or Halt($db->ErrorMsg());
И при рефреше каждые 5-ть сек:
Код: Выделить всё
$rs = $db->SelectLimit("SELECT U.FIO, U.ISVIP, M.* FROM USERS U, MESSAGES M
WHERE (U.USERID=M.USERFK AND MESSAGEID>$lastmsg)
ORDER BY M.DATETIME", $confv["messageCount_refresh"], -1) or Halt($db->ErrorMsg());
и
Код: Выделить всё
$reply = $db->GetRow("SELECT U.FIO, M.* FROM USERS U, MESSAGES M
WHERE (U.USERID=M.USERFK AND M.MESSAGEID=".$newmsg[$name]['replymid'].")") or Halt($db->ErrorMsg());
Добавлено: 25 окт 2005, 13:27
Ivan_Pisarevsky
У меня есть 2-а генератора(users, messages) и соответственно при инсерте в таблицу срабатывает событие. А для чего еще ты предлагаешь использовать события?
Это видимо(поглядемши в потолок

) срабатывает таки триггер на втсавку, а не генерируется ивент. А ивенты вместо того чтоб сервер не долбать каждые 5 секунд новым селектом.
Добавлено: 25 окт 2005, 13:28
Dimitry Sibiryakov
CREATE INDEX IDX_MESSAGES1 ON MESSAGES (USERFK);
CREATE INDEX IDX_MESSAGES2 ON MESSAGES (REPLYMID);
CREATE UNIQUE INDEX IDX_MESSAGES3 ON MESSAGES (MESSAGEID);
CREATE INDEX IDX_ONLINE1 ON ONLINE (USERFK);
CREATE UNIQUE INDEX IDX_USERS1 ON USERS (USERID);
Эти индексы убить сразу и насмерть. Для PK и FK индексы создаются автоматически и твои будут только вводить оптимизатор в заблуждение.
Добавлено: 25 окт 2005, 14:12
avenger
Структура приняла next вид:
Код: Выделить всё
CREATE GENERATOR MESSAGEID;
CREATE GENERATOR USERID;
CREATE TABLE MESSAGES (
MESSAGEID INTEGER NOT NULL,
DATETIME INTEGER NOT NULL,
USERFK INTEGER NOT NULL,
"MESSAGE" VARCHAR(5000) NOT NULL,
REPLYMID INTEGER,
STATUS SMALLINT NOT NULL
);
CREATE TABLE ONLINE (
USERFK INTEGER NOT NULL,
LASTTIMEREFRESH INTEGER NOT NULL
);
CREATE TABLE USERS (
USERID INTEGER NOT NULL,
LOGIN VARCHAR(40) NOT NULL,
"PASSWORD" VARCHAR(40),
FIO VARCHAR(200) NOT NULL,
AREA VARCHAR(200),
ORGANIZATION VARCHAR(200),
ISVIP SMALLINT NOT NULL,
ISINFOUPDATE SMALLINT NOT NULL,
ISACTIVE SMALLINT NOT NULL
);
ALTER TABLE MESSAGES ADD CHECK (STATUS IN (0,1,2));
ALTER TABLE USERS ADD CHECK (ISVIP IN (0,1));
ALTER TABLE USERS ADD CHECK (ISINFOUPDATE IN (0,1));
ALTER TABLE USERS ADD CHECK (ISACTIVE IN (0,1));
ALTER TABLE USERS ADD UNIQUE (LOGIN);
ALTER TABLE MESSAGES ADD PRIMARY KEY (MESSAGEID);
ALTER TABLE ONLINE ADD PRIMARY KEY (USERFK);
ALTER TABLE USERS ADD PRIMARY KEY (USERID);
ALTER TABLE MESSAGES ADD FOREIGN KEY (USERFK) REFERENCES USERS (USERID) ON DELETE CASCADE;
ALTER TABLE MESSAGES ADD FOREIGN KEY (REPLYMID) REFERENCES MESSAGES (MESSAGEID) ON DELETE CASCADE;
ALTER TABLE ONLINE ADD FOREIGN KEY (USERFK) REFERENCES USERS (USERID) ON DELETE CASCADE;
Можно поподробнее об ивентах?
Добавлено: 25 окт 2005, 14:15
avenger
Ivan_Pisarevsky писал(а):Это видимо(поглядемши в потолок

) срабатывает таки триггер на втсавку, а не генерируется ивент. А ивенты вместо того чтоб сервер не долбать каждые 5 секунд новым селектом.
Наверно стоит уточнить: чат пишется на php. Ивенты соответственно не
могу обрабатывать.
Может есть советы по оптимизации настроек fb в fb.conf. Т.е. предложения по настройке кэша,...
Добавлено: 25 окт 2005, 14:41
kdv
эх... alter table при добавлении PK/FK/UNIQUE пишется например так:
alter table add CONSTRAINT FK_TABLE1 foreign key (field) references (pkfield).
потому что если тебе вдруг понадобится изменить или удалить этот FK, ты сделаешь просто
alter table drop constraint CONSTRAINT_NAME.
В противном случае тебе придется шарить по системным таблицам, в поисках автоматически созданных имен constraint типа INTEG10, INTEG11 и т.п.
По производительности запросов - сначала выполняют запрос, смотрят его план, потом смотрят, есть или нет нужные индексы (добавить, убрать).
Добавлено: 25 окт 2005, 15:02
avenger
Первая загрузка модуля Refresh делает запросы:
Код: Выделить всё
--------------------------------------------------------------------------------
(firebird): SELECT ISACTIVE FROM USERS WHERE USERID=177
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
(firebird): UPDATE ONLINE SET LASTTIMEREFRESH=1130237695 WHERE USERFK=177
--------------------------------------------------------------------------------
(firebird): SELECT USERFK FROM ONLINE
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
(firebird): SELECT USERID, FIO, AREA, ORGANIZATION, ISVIP FROM USERS WHERE USERID IN (177)
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
(firebird): SELECT USERFK FROM ONLINE WHERE LASTTIMEREFRESH < 1130237635
--------------------------------------------------------------------------------
(firebird): SELECT MAX(MESSAGEID) FROM MESSAGES
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
(firebird): SELECT FIRST 20 U.FIO, U.ISVIP, M.* FROM USERS U, MESSAGES M WHERE (U.USERID=M.USERFK AND MESSAGEID>12) ORDER BY M.DATETIME
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
(firebird): SELECT U.FIO, M.* FROM USERS U, MESSAGES M WHERE (U.USERID=M.USERFK AND M.MESSAGEID=6)
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
(firebird): SELECT U.FIO, M.* FROM USERS U, MESSAGES M WHERE (U.USERID=M.USERFK AND M.MESSAGEID=5)
--------------------------------------------------------------------------------
Добавлено: 25 окт 2005, 15:10
kdv
ты к чему это все шлешь? чтобы тебе сказали, хорошие запросы или плохие? ну, нормальные запросы....
Добавлено: 25 окт 2005, 15:15
avenger
kdv писал(а):ты к чему это все шлешь? чтобы тебе сказали, хорошие запросы или плохие? ну, нормальные запросы....
Вот это смущает:
Код: Выделить всё
SELECT USERID, FIO, AREA, ORGANIZATION, ISVIP FROM USERS WHERE USERID IN (177)
Как лучше сделать если в in скажем 20 значений: 20 select-ов соответственно или один но с in-ом?
Добавлено: 25 окт 2005, 15:21
avenger
Всем огромное спасибо!!!!!!!!!! Но хотелось напоследок услышать совет по настройке кэширования в FB1.5 for winnt2000.
Что за параметры DefaultDbCachePages, SortMemBlockSize и стоит вообще их менять?
Добавлено: 25 окт 2005, 17:38
kdv
там же рядом с параметрами написано, зачем они и чего в них писать.