Медленная запись на диск MSAccess - PullRequest
2 голосов
/ 29 ноября 2008

Я пытаюсь написать программу VB.Net, которая ежедневно сохраняет 1-2 миллиона записей из 5 полей (плюс индексированный идентификатор) в таблицу MSAccess. Процесс сохранения в настоящее время занимает 13-20 часов, что, очевидно, не может быть правильным.

Это плоская таблица с минимальной индексацией, в настоящее время только 156 МБ. За исключением одного двойного поля, поля представляют собой небольшие строки, даты или длинные значения. Сам диск представляет собой 15 000 SATA, который используется только для этого файла. Компьютер и программа больше ничего не делают во время процедуры сохранения. Процедура сохранения - это простой цикл FOR-NEXT, который выдает короткий и простой оператор INSERT для каждой записи в наборе данных.

Кто-нибудь получил идеи о том, что мне нужно изменить, чтобы заставить это работать лучше?

Ответы [ 20 ]

2 голосов
/ 29 ноября 2008

Уловка, которая может работать на любой СУБД для существенного ускорения вставки, заключается в том, чтобы временно отключить индексы, внешние ключи и ограничения перед массовой вставкой данных, а затем снова включить их после того, как ваши данные в базе данных.

Особенно индексы могут снижать производительность при последовательной вставке, быстрее по крайней мере на порядок (иногда на 2!) Величины сначала заполнить таблицу, а затем создать индекс по уже заполненным данным, чем вставлять с индексом в место. В этом случае вам может потребоваться удалить индекс, а затем воссоздать его.

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

И тогда вы могли бы получить еще один крошечный прирост, используя наборы записей DAO вместо ADO - я заметил это еще во времена, когда я разрабатывал в VB6, возможно, это больше не относится к ADO.NET

1 голос
/ 30 ноября 2008

Хорошо, вернемся из долгого обеда.

ПОЛ, ПИНЕДА, ваши предположения, что проблема с индексацией ПК, были правильными. Избавился от индекса, и внезапно он хранит 40000 записей в минуту, достаточно быстро, чтобы выполнить весь день за час. И это не влияет на скорость приложений, которые используют данные вообще.

Остальные щедрые люди ... Я оставлю ваши предложения до конца дня и, надеюсь, получу их еще лучше.

Вы были чрезвычайно полезны. Я всем вам должен пиво.

1 голос
/ 01 декабря 2008

Была ли включена функция автоматической фиксации?

Это действительно замедлило бы вас, поскольку каждую вставку нужно было бы написать физически на диск до того, как будет обработан следующий.

Попробуйте вручную фиксировать примерно каждые 1000 вставок.

1 голос
/ 29 ноября 2008

Вы должны действительно управлять массовой вставкой. Каждая вставка имеет много накладных расходов, и, выполняя по одной строке за раз в цикле For next, вы тратите более 2/3 мощности компьютера. Если данные поступают по одной строке за раз, вам нужно будет создать буфер для их сбора перед тем, как вставить массив в базу данных. Кибби предложил записать данные в CSV-файл, а затем сбросить их в базу данных, и если вам нужно записать данные, это хороший метод. Я бы рекомендовал собирать данные в памяти по несколько минут за один раз.

0 голосов
/ 30 ноября 2008

Doofledorfer: вот 5 строк выборочного ввода, как вы и просили, хотя я действительно думаю, что сейчас на правильном пути с предложением вставки блока и первичным ключом без индекса

INSERT INTO Ticks (Symbol, TickDate, TickTime, TickPRice, TickVolume) 
VALUES ('SPY', #11/28/2008#, #09:30:00#, 88.63, 200);

INSERT INTO Ticks (Symbol, TickDate, TickTime, TickPRice, TickVolume) 
VALUES ('SPY', #11/28/2008#, #09:30:00#, 88.62, 400);

INSERT INTO Ticks (Symbol, TickDate, TickTime, TickPRice, TickVolume) 
VALUES ('SPY', #11/28/2008#, #09:30:00#, 88.62, 100);

INSERT INTO Ticks (Symbol, TickDate, TickTime, TickPRice, TickVolume) 
VALUES ('SPY', #11/28/2008#, #09:30:00#, 88.62, 300);

INSERT INTO Ticks (Symbol, TickDate, TickTime, TickPRice, TickVolume) 
VALUES ('SPY', #11/28/2008#, #09:30:00#, 88.62, 127);
0 голосов
/ 29 ноября 2008

опс, пропустил один из твоих вопросов STEPHBU ... Я позволяю индексированному идентификатору автоматически увеличиваться, а не пытаюсь назначить его в инструкции INSERT. Хорошая мысль, хотя!

0 голосов
/ 29 ноября 2008

Спасибо за ваши вопросы, Пол.

Использование файла подкачки составляет 600 МБ, ЦП составляет около 5% большую часть времени, с скачками до 80% каждые 20 секунд или около того. Память: всего 2 ГБ, доступно 1,3 ГБ, системный кэш 1 ГБ.

Да, это выглядит линейно, первые 15 000 записей занимают 10 минут.

Что касается индекса, я не пробовал этого, но Access всегда жалуется, если вы не проиндексировали хотя бы поле идентификатора.

Показания ввода-вывода кажутся очень большими, однако, почти 6 МБ после 20 минут работы и только 25 000 записей.

0 голосов
/ 05 декабря 2008

CodeSlave .... Это верный момент, и если все это сработает, мне придется потратить деньги на SQL Server или что-то подобное, не говоря уже о еще паре компьютеров. Пока я не хочу вкладывать деньги или обучение.

Мистер Андерсон ... Еще не пробовал, а я буду. Но сейчас, по другим предложениям, мое время экономии 10-20 часов сократилось до 15 минут, поэтому я очень доволен своим отдыхом.

0 голосов
/ 29 ноября 2008

Попробуйте режим блокировки = 0 - это уровень страницы. 800 об / с (записей в секунду) дает 480000 записей в 10 минут - вы имели в виду 800 об / мин?

0 голосов
/ 29 ноября 2008

Вот несколько замечаний по запросу добавления для текстового файла с разделителями, боюсь, VBScript, но это может помочь.

Set cn = CreateObject("ADODB.Connection")
strFile="C:\ltd.mdb"
strCon="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
& strFile & ";" 

cn.Open strCon

strSQL="INSERT INTO tableX ( Name1,Name2 ) " _
& "SELECT Name1,Name2 " _
& "FROM [ltd.txt] IN '' [Text;Database=c:\docs\;HDR=YES;]"

cn.Execute strSQL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...