Вниз
Скачать: CL | DM;

Быстая работа с большой базой   Найти похожие ветки 

← →
ZedeS ©   (2005-09-30 17:01) [0]

Доброго времени суток.
Проблема следующего характера:
Надо за приемлемое время (1-2 мин) обработать (прочитать значения 5 полей и произвести нехитрые вычисления)приблизительно 1 млн. записей.
Сейчас использую Delphi и Access через ADO.
На P4 2.4G и 512Mb - 100 000 записей обрабатывается за 2,5 мин
Чем лучше заменить Access или надо вводить многопоточность.
Заранее благодарен


← →
Desdechado ©   (2005-09-30 17:10) [1]

откуда такие ограничения?
заменить на нормальный SQL-сервер, коих много


← →
Zedes ©   (2005-09-30 17:14) [2]


> откуда такие ограничения?
> заменить на нормальный SQL-сервер, коих много

Весь софт должен быть лицензионный


← →
Fay ©   (2005-09-30 17:15) [3]

MSDE | MSSQL2005 Express


← →
Виталий Панасенко   (2005-09-30 17:29) [4]

Оно то так.. Но если все-таки действительно нужно время.. Это как ломать пароль из более чем 6-7 и более символов.. Чтобы было быстро - нужен СУПЕР-комп, а не персоналка.. Мое мнение.


← →
Zedes ©   (2005-09-30 17:35) [5]


> нужен СУПЕР-комп

Это уже последний этап оптимизации. Для начала нужно подобрать софт


← →
Виталий Панасенко   (2005-09-30 17:40) [6]


> Zedes ©   (30.09.05 17:35) [5]
>
> > нужен СУПЕР-комп
>
> Это уже последний этап оптимизации. Для начала нужно подобрать
> софт

А глянуть на выполняемые расчеты ?


← →
Zedes ©   (2005-09-30 17:44) [7]


> А глянуть на выполняемые расчеты ?


Расчеты ерундовые.
3 поля проверяются на соответствие 3 переменным, если соответсвие есть, то 2 из 5 полей просто копируются в отчет


← →
Desdechado ©   (2005-09-30 17:49) [8]

я вообще-то про временнЫе ограничения спрашивал
да и код "проверок 3 полей" оптимизировать надо, стесняешься?


← →
AlexWlad ©   (2005-09-30 19:36) [9]

Access - фтопку... Только полноценный SQL-сервер... Как можно бОльшую часть расчетов/логики - в ХП... Ну и оптимизация, конечно.


← →
app ©   (2005-09-30 19:57) [10]

Zedes ©   (30.09.05 17:44) [7]
Намек на навигационные методы понят.


← →
Sashka ©   (2005-10-01 20:47) [11]


> Расчеты ерундовые.
> 3 поля проверяются на соответствие 3 переменным

А если проверку в where запихнуть? В отчёт-то много записей попадает?


← →
Loginov Dmitry   (2005-10-01 21:23) [12]

access+ado+delphi жизненно несовместимы, скорость действительно падает в сотни раз. Используй другие методы доступа к данным


← →
sniknik ©   (2005-10-01 21:45) [13]

> access+ado+delphi жизненно несовместимы, скорость действительно падает в сотни раз.
надо добавлять - при "умелом" использовании... ;)

на самом деле access(база)+ado+delphi в случае одного юзера на локальной машине гораздо быстрее (процентов на 20-30) чем mssql в техже условиях (один юзер и сервер на одной машине с клиентом).
конечно если рассматривать то что у них примерно однофункционально, если mssql чтото умеет по устественным образом а в access приходится извращатся... ну тут и скорости другие.
так же как если разнести базу и клиента на разные машины... или подключить 15 конектов к одной базе. тут тоже необходим будет перерасчет времени, и будет он не впользу access, но не в сотни раз ;), цифры будут поскромнее.


← →
Danilka ©   (2005-10-03 08:21) [14]

Zedes ©   (30.09.05 17:44)

> А глянуть на выполняемые расчеты ?

Расчеты ерундовые.
3 поля проверяются на соответствие 3 переменным, если соответсвие есть, то 2 из 5 полей просто копируются в отчет


Используй SQL запросы + индекс по 3-м "проверяемым" полям, и будет тебе щастье, на твоих мильенах. :)


← →
Danilka ©   (2005-10-03 08:29) [15]

sniknik ©   (01.10.05 21:45)
конечно если рассматривать то что у них примерно однофункционально, если mssql чтото умеет по устественным образом а в access приходится извращатся...


А оно надо, использовать только ту функциональность, которая есть в Аццессе? :)
А как-же триггеры, TSQL и тд.? :)
Думаю, правильная база, заточеная под MSSQL, использующая его возможности, которые отсутствуют в аццессе может уделать легко по скорости аццесс и при однопользовательском доступе.
Конечно, если это не БД из двух таблиц, а что-то посерьезнее. :))


← →
sniknik ©   (2005-10-03 09:14) [16]

> Думаю, правильная база, заточеная под MSSQL, использующая его возможности ... уделать легко по скорости ...
именно это и имел в виду когда оговаривал что если сравнивать ~ однофункциональное.

кстати если ли уж зашла речь о функциональности то не такая она и маленькая в access. самая большая для баз позиционирующихся как локальные.


← →
isasa ©   (2005-10-03 10:58) [17]

Немного в тему и нет. Рекомендую посмотреть размер файла подкачки в разделе "Виртуальная память".
По умолчанию ~1.5 ОП - поставить 512..1024М. Очень помогает.


← →
Zedes ©   (2005-10-04 16:33) [18]

Тест показал, что почти все время тратится на чтение записей из БД.
200 000 записей читаются в StringGrid приблизительно 8 мин, а дальнейшая обработка занимает 40 сек.
В этом проекете БД не инструмент, а способ собрать (и не потерять) записи, за определенный период времени. Никакой предварительной обработки (при добавлении в БД например) не получается, поэтому ни триггеры, ни хранимые процедуры, ни автовычисляемы поля никуда не приткнеш.
Нужно чтобы приложение бысто считывало инфу из базы.
Какую БД взять (либо дешевую, либо free)?


← →
sniknik ©   (2005-10-04 16:42) [19]

app ©   (30.09.05 19:57) [10]
> Zedes ©   (30.09.05 17:44) [7]
> Намек на навигационные методы понят.
оказалось все гораздо "хужее" ;) ->

Zedes ©   (04.10.05 16:33) [18]
> 200 000 записей читаются в StringGrid приблизительно 8 мин.

> Какую БД взять (либо дешевую, либо free)?
любую. с такими подходами тормоза неизбежны, на любой базе... но можно решить "железно", т.е. перенести задачу на суперкомпьютер (крей или как там их зовут)... ;о))


← →
Zedes ©   (2005-10-04 16:50) [20]

Тест показал, что почти все время тратится на чтение записей из БД.
200 000 записей читаются в StringGrid приблизительно 8 мин, а дальнейшая обработка занимает 40 сек.
В этом проекете БД не инструмент, а способ собрать (и не потерять) записи, за определенный период времени. Никакой предварительной обработки (при добавлении в БД например) не получается, поэтому ни триггеры, ни хранимые процедуры, ни автовычисляемы поля никуда не приткнеш.
Нужно чтобы приложение бысто считывало инфу из базы.
Какую БД взять (либо дешевую, либо free)?


← →
Виталий Панасенко   (2005-10-04 16:59) [21]


> Zedes ©   (04.10.05 16:50) [20]
> Тест показал, что почти все время тратится на чтение записей
> из БД.
> 200 000 записей читаются в StringGrid приблизительно 8 мин,
>  а дальнейшая обработка занимает 40 сек.

А на кой в StringGrid ? И вообще, нужно ли СНАЧАЛА ЧИТАТЬ, А ПОТОМ ОБРАБАТЫВАТЬ ? Может, одновременно лучше ? Т.е. ПО МЕРЕ СЧИТЫВАНИЯ ? Настройки подключения (особенно, CursorLocation.. Установи "на сервере")


← →
Anatoly Podgoretsky ©   (2005-10-04 17:08) [22]

Zedes ©   (04.10.05 16:50) [20]
TStringGrid служит для визуализации!!!


← →
Anatoly Podgoretsky ©   (2005-10-04 17:10) [23]

sniknik ©   (04.10.05 16:42) [19]
Много хуже, я такого даже и предположить не мог.


← →
Карелин Артем ©   (2005-10-04 19:39) [24]


> Zedes ©   (04.10.05 16:50) [20]

БД тут не причем.  Следующий код на 1 746 229 записях выполняется 4 секунды на Firebird.

procedure TForm1.Button1Click(Sender: TObject);
var s:TStringList;
   i,j:integer;
begin
i:=GetTickCount;
s:=TStringList.Create;
IBSQL1.ExecQuery;
while not(IBSQL1.Eof) do
begin
 S.Add(IBSQL1.Fields[3].AsString);
 IBSQL1.Next;
 inc(j);
end;
ShowMessage(IntToStr(GetTickCount-i)+" "+IntToStr(j));
s.Free;
end;


← →
Anatoly Podgoretsky ©   (2005-10-04 20:03) [25]

Бр, какой не хороший код. Измеряй без  S.Add(IBSQL1.Fields[3].AsString);


← →
Карелин Артем ©   (2005-10-05 09:03) [26]


> Anatoly Podgoretsky ©   (04.10.05 20:03) [25]

А что такого нехорошего? Обращение по номеру поля? Так это чисто для скорости.


← →
msguns ©   (2005-10-05 09:18) [27]

>Карелин Артем ©   (05.10.05 09:03) [26]
>А что такого нехорошего? Обращение по номеру поля? Так это чисто для скорости.

1. Почему для селекта исп-ся ExecSQL ?
2. Нет обработки ошибок
3. Общий стиль: эти Button1, IBSQL1
4. Нет инициализации j, да и вообще не понятно, нафиг она нужна, если общее число записей после сигнала EOF можно получить из RecordCount
5. Совершенно неясно, что тут делает стрингрид, который нигде на экране не присутствует.


← →
msguns ©   (2005-10-05 09:20) [28]

5 пункт прошу не читать. Глючнуло ;)))


← →
sniknik ©   (2005-10-05 11:00) [29]

Карелин Артем ©   (04.10.05 19:39) [24]
ну во первых у автора не StringList а StringGrid, обращения к которому на порядок медленнее, добавления не "интелектуальны" (нет блочного выделения памяти "наперед"), и каждая строка грида есть список (у тебя создается только один). + вполне вероятно что кроме всего прочего грид у него отображается на форме в момент вдобавлений...
т.е. твое сравнение в "корне неправильное".
вывод "БД тут не причем." верен, но непонятно (в свете теста) на чем основан.  

а во вторых добавленные значения после нигде не используются... на месте оптимизатора я бы его вообще выкинул из данного кода нафиг ;), всю переменную s.  но как там на самом деле смотреть не хочется.


← →
ANB ©   (2005-10-05 11:14) [30]


> Zedes ©   (04.10.05 16:33) [18]

В принципе и акссес умеет с SQL работать. Зачем считывать все данные на клиента - не очень понятно - уйдет уйма оперативки и ессно будет тормозить.
Решение :
1. Довесить на таблицу индексы
2. Написать нормальный SQL запрос (смотреть sum, count, group by, where, iif)

Все должно довольно шустро обработаться.


← →
Anatoly Podgoretsky ©   (2005-10-05 11:36) [31]

Карелин Артем ©   (05.10.05 09:03) [26]
Нехорошо, что для измерения скорости ты привлек сюда зачем то TSringList, c которым работаешь самым неоптимальным путем, постоянно перераспределяешь память.

Ты что хочел замерить скорость заполнения TSringList, а вопрос то про базу. Кроме того у автора TSringGrid, что на порядке хуже.


← →
Карелин Артем ©   (2005-10-05 11:54) [32]


> msguns ©   (05.10.05 09:18) [27]


> 1. Почему для селекта исп-ся ExecSQL ?

> 4. Нет инициализации j, да и вообще не понятно, нафиг она
> нужна, если общее число записей после сигнала EOF можно
> получить из RecordCount


Ты случаем не спутал Dataset с TIBSQL???

> 2. Нет обработки ошибок

На фига это тут? Это же не реально используемый код.

> sniknik ©   (05.10.05 11:00) [29]

Почитай строку 1 моего поста и посмотри куда она ссылается. Проделав все это может и поймешь к чему я писал.
Все нормально работает, 500 мегов примерно памяти хавает в процессе.

Развернутый блин вывод из теста:
1) Как можно заметить, данные из базы в случае использования самых легких и некэширующих компонентов загружаются со скоростью вжика.
2) Проблема в TSringGrid и кэшировании на клиенте.


← →
Карелин Артем ©   (2005-10-05 12:04) [33]

Насчет переменной каюсь - неаккуратно вырезал часть кода из общей кучи.


← →
Seg   (2005-10-05 12:15) [34]

А может взять Оракл и курсором прочитать все записи?


← →
msguns ©   (2005-10-05 14:43) [35]

>Карелин Артем ©   (05.10.05 11:54) [32]
>Ты случаем не спутал Dataset с TIBSQL???

Нет, не спутал. Перефразирую вопрос:
Зачем для получения НД на клиенте используется TIBSQL вместо куда более удобных для этой цели TIBDataSet или, если НД не требуется редактировать, TIBQuery с методом Open ?

Возможно, ты посчитаешь это придиркой, но ведь на замечание АП о "страшности" кода сам же полез на рожон, чем и вызвал критику приведенного тобою кода ;)


← →
Карелин Артем ©   (2005-10-05 17:28) [36]


> msguns ©   (05.10.05 14:43) [35]

Отвечу вопросами на вопрос :)
1) Зачем использовать набор данных, загружающий всю инфу в память на клиенте, если нет необходимости в Data-aware компонентах?
2) Зачем использовать компонент, работающий как минимум на порядок медленнее?

Если у меня в случае TIBSQL ушло полгига под прочитанные данные, то сколько уйдет еще и при перемещении набора данных в конец? Про UniDirectional ни строчки не было ;)


← →
eJack   (2005-10-07 05:47) [37]

Попробуй сжать базу перед работай
procedure CompactDatabase_JRO(DatabaseName: string; DestDatabaseName: string =
 ""; Password: string = "");
const
 Provider = "Provider=Microsoft.Jet.OLEDB.4.0;";
var
 TempName: array[0..MAX_PATH] of Char; // имя временного файла
 TempPath: string; // путь до него
 Name: string;
 Src, Dest: WideString;
 V: Variant;
begin
 try
   Src := Provider + "Data Source=" + DatabaseName;
   if DestDatabaseName <> "" then
     Name := DestDatabaseName
   else
   begin
     // выходная база не указана - используем временный файл
     // получаем путь для временного файла
     TempPath := ExtractFilePath(DatabaseName);
     if TempPath = "" then
       TempPath := GetCurrentDir;
     //получаем имя временного файла
     GetTempFileName(PChar(TempPath), "mdb", 0, TempName);
     Name := StrPas(TempName);
   end;
   DeleteFile(PChar(Name)); // этого файла не должно существовать :))
   Dest := Provider + "Data Source=" + Name;
   if Password <> "" then
   begin
     Src := Src + ";Jet OLEDB:Database Password=" + Password;
     Dest := Dest + ";Jet OLEDB:Database Password=" + Password;
   end;

   V := CreateOleObject("jro.JetEngine");
   try
     V.CompactDatabase(Src, Dest); // сжимаем
   finally
     V := 0;
   end;
   if DestDatabaseName = "" then
   begin // т.к. выходная база не указана
     DeleteFile(PChar(DatabaseName)); //то удаляем не упакованную базу
     RenameFile(Name, DatabaseName); // и переименовываем упакованную базу
   end;
 except
   // выдаем сообщение об исключительной ситуации
   on E: Exception do
     ShowMessage(e.message);
 end;
end;

И незабывай про индескы, создай их динамически (если их нет), а потом удали, если они не нужны. И все будет ОК.



Страницы: 1 вся ветка

Скачать: CL | DM;



Память: 0.56 MB
Время: 0.027 c
2-1130756736
Ильичев С.А.
2005-10-31 14:05
2005.11.20
ADO, Parametr, NULL


2-1130852396
Starcom
2005-11-01 16:39
2005.11.20
Прочитать определённую ветвь системного реестра...


14-1130401937
nk
2005-10-27 12:32
2005.11.20
Мини АТС Рanasonic KX-TD1232


9-1120860136
FRick
2005-07-09 02:02
2005.11.20
GLScene AVI Recorder


1-1130407173
WondeRu
2005-10-27 13:59
2005.11.20
Как сделать потомка ActiveX формы?




   Наверх