Я использую TClientDataSet в приложении для управления загрузкой данных, импортированных из нескольких файлов CSV. Всего это может быть миллион или более записей. Я хочу иметь возможность удалить все записи набора данных, связанные с конкретным CSV-файлом, но время на удаление большого количества элементов очень медленное.
В качестве теста, чтобы попытаться разобраться, делаю ли я что-нибудь глупое, я создал простое консольное приложение. Все, что он делает, это:
Создайте экземпляр TClientDataSet с 1 определенным полем (ID):
CDS := TClientDataSet.Create(nil); CDS.FieldDefs.Add('ID', ftInteger); CDS.CreateDataSet; CDS.LogChanges := False;
Добавить 100000 элементов (занимает 0,1 секунды):
for i := 1 to 100000 do begin CDS.AppendRecord([i]); end;
Удалить 50000 элементов (занимает ~ 4 секунды или ~ 4,4 секунды с
LogChanges=TRUE
):CDS.First; while CDS['ID'] <= 50000 do CDS.Delete;
Если бы в моем наборе данных было 1,5 миллиона элементов, и я хотел бы удалить 0,5 миллиона записей, то удаление элементов этим методом заняло бы так много времени, что я даже не смог бы его измерить.
В качестве временного решения мне нужно создать новый набор данных, затем скопировать все элементы, которые я хочу сохранить, в новую копию и удалить исходную копию. Если я не удаляю только небольшой% записей из исходного набора данных, этот метод работает намного быстрее.
Возможно, я не использую наиболее подходящий метод для удаления элементов из набора данных? Я предполагаю, что это вызывает кучу внутренней обработки с каждым удаленным элементом. Есть ли способ удалить сразу несколько элементов, которые мне не хватает? Возможно, я могу установить индекс и диапазон на основе этого индекса, а затем удалить все элементы в текущем диапазоне с помощью одной операции?
Может проблема в ClientDataSet, а не во мне? Возможно, мне нужно использовать другой компонент. Какие-либо предложения?
LogChanges
. - person Ondrej Kelle   schedule 14.08.2016Append/Set/Post
наCDS.AddRecord([I]);
, я получаю 73 мс, чтобы добавить 100000 строк, и 3883 мс (3,9 секунды), чтобы удалить первые 50000. - person Ken White   schedule 15.08.2016CDS.APPENDRECORD([I])
. Это определенно было немного быстрее, чем использованиеAppend/Set/Post
для добавления элементов. - person Phil B   schedule 15.08.2016