![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Очень быстрое добавление изменение записи... [D7]
Rouse_ © (2004-05-16 11:08:00)Имеется база (Access) более 150 тысяч записей...
Необходимо в таблице создать еще одну колонку и заполнить ее неким числом...
Колонку создаю вот так:
SourceQuery.SQL.Text := 'Alter Table ' + sTitTable + ' Add ' + FIELD_REINDEX + ' Char(50)';// CONSTRAINT ' + S.Strings[0] + ' PRIMARY KEY';
SourceQuery.ExecSQL;
где sTitTable - имя таблицы
FIELD_REINDEX - имя колонки
и начинаю модифицировать это поле в каждой записи:
SourceDS.DataSet.First;
while not SourceDS.DataSet.Eof do
begin
SourceDS.DataSet.Edit;
try
SourceDS.DataSet.FieldValues[FIELD_REINDEX] := GenerateGUID;
finally
SourceDS.DataSet.Post;
end;
SourceDS.DataSet.Next;
end;
Проблема заключается в чем:
на довольно мощной мацине (Xeon 3.2 1Gb Dual Memory) этод код модифицирует около 4 записей в секунду, т.е. всю базу он пробежит за примерно 10 часов...
Вопрос: Как можно ускорить модификацию записей в базе?
sniknik (2004-05-17 10:36:00) [21]> Ругается зараза на MaxLockPerFile - мол превышено кол-во блокировок файла...
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Jet 4.0\MaxLockPerFile
увеличь, по умолчанию там значение 9500, на одиночной таблице полное обновление я на 170 000 записей ставил 19500 (приблизительно также поставь, после взад верни :).
Rouse_ (2004-05-17 10:29:00) [22]> добавляеш таблице поле типа "Счетчик"
Ругается зараза на MaxLockPerFile - мол превышено кол-во блокировок файла...
sniknik (2004-05-16 21:09:00) [23]> Очень быстрое добавление изменение записи...
> Ключевых полей в базе нет индексированных тоже (вот такая вот беда)...
самый быстрый способ, в такой ситуации (имхо).
добавляеш таблице поле типа "Счетчик" (делать надо в конструкторе самого аксеса), ставиш ему размерность (в свойствах) "Код репликации" и назначакш его ключем. все. выходиш с подтверждением сохранения макета таблицы. гуиды проставятся автоматом. очень быстро.
то же самое можно через ADOX реализовать (в SQL почемуто не нашол установку типов полей, возможно нет этого), только неохота искать в хелпе, если нужно найдеш (???).
Polevi (2004-05-16 18:36:00) [24]будь здоров :)
Rouse_ (2004-05-16 18:31:00) [25]> [13] Polevi © (16.05.04 18:27)
Урррра, зарработала!!! :))) © Кот Матроскин
Всем кто принял участие большое спасибо :))
Сергею в часности :)
Polevi (2004-05-16 18:27:00) [26]и у ф-ии параметр, соотв :)
Polevi (2004-05-16 18:27:00) [27]попробуй
UPDATE REG21 SET ID = CoGenerateGUID(SomeFieldValue);
Rouse_ (2004-05-16 18:25:00) [28]Хех, вот запрос: UPDATE REG21 SET ID = CoGenerateGUID();
Результат, как и в предыдущем варианте - у всех записей одинаковый GUID
5546D6C3124561B347965CA919372AD1842
Это уже в самом Access - е проверил, без Дельфи...
Беда :(
Polevi (2004-05-16 18:17:00) [29]что значит проверял
запрос отработал ?
Rouse_ (2004-05-16 18:15:00) [30]> [8] Polevi © (16.05.04 18:03)
В Access проверял ее, а вызывал уже из программы, сейчас попробую совет Mike Kouzmine © :)
Mike Kouzmine (2004-05-16 18:11:00) [31]Построй запрос в аксессе, там используй эту функцию, а из делфи работай с запросом, как с хранимой процедурой.
Polevi (2004-05-16 18:03:00) [32]из Access вызывал ?
Rouse_ (2004-05-16 17:55:00) [33]Такс...
Функцию написал, вот теперь вопрос, как ее правильно вызвать?
Вот так:
SourceQuery.SQL.Text := 'UPDATE ' + sTitTable + ' SET '+ FIELD_REINDEX + ' = Module1.CoGenerateGUID()';
Не проходит, пишет неопределенная функция Module1.CoGenerateGUID()
Где про это почитать можно?
если интересно то вот как выглядит сама функция...
Option Compare Database
Public Function CoGenerateGUID() As String
Dim Counter, Dat As Integer
Dim Result As String
Dim HexCode
HexCode = Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", F)
Result = ""
Counter = 0
Randomize
Do While Counter < 36
Dat = (15 * Rnd) + 1
If Dat > 15 Then Dat = 15
Result = Result + HexCode(Dat)
Counter = Counter + 1
Loop
CoGenerateGUID = Result
End Function
это так - набросок, главное чтоб возвращала какое нибудь уникальное значение...
Rouse_ (2004-05-16 17:18:00) [34]Угу - попробую, если что получится - сообщу :)
Спасибо :)
Polevi (2004-05-16 17:15:00) [35]не макрос
в Access можно писать ф-ии на васике, если ты не в курсе
затем эти ф-ии можно использовать в запросах
UPDATE ... SET Field1=MyGlobalFunctionFromModule()
там чтото вроде модудля данных надо создать а в нем public function
Точно не могу сказать давно не работал с Access и сейчас не установлен у меня
Rouse_ (2004-05-16 17:09:00) [36]> [3] Polevi © (16.05.04 16:47)
В смысле? Т.е. необходимо в базу добавить некий макрос и вызывать уже его?
Polevi (2004-05-16 16:47:00) [37]ф-ию напиши на Access
в запросе полю присваивай значение ф-ии
Rouse_ (2004-05-16 16:12:00) [38]> WHERE ID = :ID
Ключевых полей в базе нет индексированных тоже (вот такая вот беда)...
Коль, а можно ли каким нибудь макаром сгенерировать все необходимые данные через запятую - а потом одним запросом перекинуть в базу?
К примеру:
SourceQuery.SQL.Text := 'UPDATE ' + sTitTable + ' SET '+ FIELD_REINDEX + ' = '+QuotedStr(GenerateGUID);
SourceQuery.ExecSQL;
Обрабатывается очень быстро - но значение во все поля заносится одинаковое, а вот как сделать чтобы в каждое поле заносилось разное?
Nikolay M. (2004-05-16 11:52:00) [39]Попробуй запросом
UPDATE mytab
SET my_field = :my_field_value
WHERE ID = :ID
Не знаю механизмов апдейта через датасет, возможно, что в твоем случае уходит запрос
UPDATE mytab
SET
field1 = value1,
field2 = value2,
...
fieldN = valueN
WHERE
ID = id_value
(т.е. апдейтятся ВСЕ поля вместо одного) что, возможно, приводит к перестройке всех существующих в таблице индексов.
Все сказанное - только предположения. Как оно происходит в аксессе на самом деле, утверждать не берусь.