Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.02.25;
Скачать: [xml.tar.bz2];




Вниз

Добавление записей в IB6 


Dmitry Alferev   (2002-01-27 00:05) [0]

Как наиболее оптимальным, т.е. быстрым образом добавлять много записей(до 1М и более) в таблицы Ib6/Firebird? Среда Delphi5.

PS: вопрос возник потому что текущая реализация тормозит по сравнению с Paradox версией почти на порядок, т.е. 10 раз... сделано сейчас через TIBSQL.



Иван Шихалев   (2002-01-27 02:19) [1]

TIBDataSet + отдельная транзакция. Возможно, стоит поиграться с параметрами транзакции. Хотя это лишь ИМХО.



Dmitry Alferev   (2002-01-27 15:24) [2]

транзакция вроде как отдельная, в отдельном треде. За одну транзакцию добавляется 5-10 тыщ записей. TIBDataSet раньше пробовал, результат тоже не впечатлил.



kaif   (2002-01-27 23:04) [3]

А данные откуда берутся, если не секрет? Из внешнего источника или это результат запроса по той же базе?



Alexandr   (2002-01-28 10:02) [4]

надо смотреть лучше и тшательней:
Что, откуда , куда и как копирутся, тогда посмотрим как ускорить
А так.
1) Самый быстрый способ - через External tables в Interbase.
2) если Force Writes на сремя заливки выключить будет гораздо быстрее
3) Индексы лучше отключить перед заливкой, и включить потом, с триггерами тоже что-то придумать, если можно.
вот так.



Dmitry Alferev   (2002-01-29 02:42) [5]

1. данные берутся из лог файлов прокси сервера

2. forced writes попробую, но сомнительно что будет быстрее на поряд, да и не дело это ИМХО

3. что такое External tables???

4. Как отключить индексы? без всяких IB Console можно это провернуть?



Alexandr   (2002-01-29 08:15) [6]

ответы.
1. Хорошо, значит нужна своя прога для расшифровки лога и запихивания в Interbase
2.Если дело в низкой скорости записи на винт, то разница будет очень ощутима, а после переноса, можно и включить.
3.Тебе оно не надо. Почитай в документации на Interbase
4.В своей программе и отключай например
alter index INDEX_NAME inactive в IBSQL или через какие компоненты ты работаешь.

Тебе надо через TIBSQL, а транзакции commit делать через несколько тыс. записей.
Никаких DataSet.
кстати, prepare сделай вначале своему IBSQL, чтобы он каждый раз не препарировался. А аргементы передавай параметрами, кстати, параметры вызывай по номеру, а не по имени.

И оптимизируй свою прогу.



Dmitry Alferev   (2002-01-31 01:00) [7]

хех. Песней и пляской, а точнее включением/выключением индексов перед добавлением записей, и уменьшением PAGE_SIZE до 1024(почему это увеличивает скорость я совершенно не врубаюсь!!!) удалось свести разницу с Парадоксом по времени с 10 раз до 3-4.

Но вылезла еще одна проблема.

Таблица:

create table TrafficEvents(MessageDate TIMESTAMP,
UserID INTEGER,
ClientIP INTEGER,
BytesIn INTEGER,
URL CHAR(80),
Protocol SMALLINT,
XWeekDay SMALLINT,
HourNum SMALLINT)!!

CREATE INDEX TRAFFICEVENTS_IDX0 ON TRAFFICEVENTS (MESSAGEDATE)!!
CREATE INDEX TRAFFICEVENTS_IDX2 ON TRAFFICEVENTS (USERID)!!
CREATE INDEX TRAFFICEVENTS_IDX3 ON TRAFFICEVENTS (CLIENTIP)!!
CREATE INDEX TRAFFICEVENTS_IDX4 ON TRAFFICEVENTS (URL)!!
CREATE INDEX TRAFFICEVENTS_IDX5 ON TRAFFICEVENTS (PROTOCOL)!!
CREATE INDEX TRAFFICEVENTS_IDX6 ON TRAFFICEVENTS (XWEEKDAY)!!
CREATE INDEX TRAFFICEVENTS_IDX7 ON TRAFFICEVENTS (HOURNUM)!!

запрос:

select Protocol, count(BytesIn), sum(BytesIn) from TrafficEvents
group by Protocol

так вот из ISQL он выполняется нормально, а из моей проги дает:

arithmetic exception, numeric overflow, or string truncation...

почему не пойму....



kaif   (2002-01-31 01:51) [8]

Эта ошибка бывает в 2 случаях:
1. Когда CHARACTER_SET не тот (при работе со строковыми полями)
2. Если число суммируемых BytesIn выскочило за пределы INTEGER
(Это вероятнее).
Может, у тебя (помнится, миллионы записей) просто сумма BytesIn насчитала больше 2 млрд. В IB6 есть тип данных INT64. Лучше как-то его задействовать, IMHO.



Dmitry Alferev   (2002-01-31 03:49) [9]

так а че он из ISQL нормально выполняется??? при этом если group by и первое поле в селекте не Protocol, а UserID или ClientIP то все ОКи...



kaif   (2002-01-31 09:24) [10]

Вообще не используй SMALLINT. Я где-то читал, что места он столько же занимает, сколько и INTEGER, а работает медленнее.
А ошибка у тебя странная... Попытайся ограничить как-то кол-во суммируемых записей с помощью WHERE. Кроме того, вместо
count(BytesIn) напиши count(*). Charset-ы, видимо, непричем, если поле URL не задействовано. Потом у тебя в таблице нету PRIMARY KEY. Я так работать не пробовал. Это может отразиться на поведении индексов. Хотя.. PRIMARY KEY и не отключишь потом.



Dmitry Alferev   (2002-01-31 19:19) [11]

kaif а ты был прав :-) дело оказалось в том что величина вылазила за границы INTEGER :-) замена типа поля на DOUBLE PRECISION спасла отца русской демократии :-) но вот почему все же в ISQL эта ошибка не вылазила - загадка.



kaif   (2002-02-01 03:26) [12]

Это интересно... А какую ISQL ты используешь? Ту, что в IBConsole IB6? Или у тебя IB5 с его WISQL? Или ты используешь какую-то DOS консоль?
Дело в том, что у меня есть исходный текст IBConsole IB6. Можно посмотреть, в чем разница твоей и их реализации запроса.




Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.02.25;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.74 MB
Время: 0.022 c
14-79447          Socol                 2001-12-28 15:04  2002.02.25  
Загрузка файла!


1-79380           Deadlock              2002-02-09 05:48  2002.02.25  
Такой вот компонент!


1-79350           Demon[DZ]             2002-02-07 11:16  2002.02.25  
TTreeView&Table


1-79366           UnDISCOvery           2002-02-08 13:51  2002.02.25  
Как сделать


1-79336           ASV                   2002-02-08 02:57  2002.02.25  
Кодировка