Займите слишком много времени для записи в Access Data Base с помощью приложения C # WPF, Visual Studio, - PullRequest
0 голосов
/ 19 марта 2019

У меня есть приложение WPF, использующее C # и VS.И я использую базу данных Access.У меня есть цикл, который должен работать в течение максимального времени 500 мс, но он занимает 570 + -

В моей программе у меня есть время ожидания ~ 340 мс и более ~ 160 мс, которые я могу оптимизировать

После проверки с помощью секундомера я обнаружил, что когда я записываю свои данные в базу данных Access, это занимает около 50 мс (у меня там 3 записи).И я понятия не имею, как оптимизировать запись в базу данных

Мой класс, который подключается и использует базу данных, - это внешний файл DLL, который выглядит следующим образом (я также привожу пример одного метода, который занимает 50 мс времени выполнения,названный как "AddDataToLocalHeaderResult"):

    namespace DataBaseManager
    {
        public class LocalPulserDBManager
        {
            private string localConnectionString;
            private string databaseName = $@"C:\Pulser\LocalPulserDB.mdb";
            private  readonly int _30DaysBack = -30;

            private static readonly Lazy<LocalPulserDBManager> lazy =new Lazy<LocalPulserDBManager>(() => new LocalPulserDBManager());

            public static LocalPulserDBManager LocalPulserDBManagerInstance { get { return lazy.Value; } }

            private void CreateConnectionString()
            {
                localConnectionString = $@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={databaseName};Persist Security Info=True";
            }

            private LocalPulserDBManager()
            {
                CreateConnectionString();
            }

public  void AddDataToLocalHeaderResult(string reportNumber,string reportDescription, 
            string catalog,string workerName,int machineNumber, Calibration c,string age)
        {
            if (IsHeaderLocalDataExist(reportNumber, catalog, machineNumber, c) == false)
            {
                using (OleDbConnection openCon = new OleDbConnection(localConnectionString))
                {
                    string query = "INSERT into [HeaderResult] ([ReportNumber],[ReportDescription],[CatalogNumber], " +
                        "[WorkerName], [LastCalibrationDate], [NextCalibrationDate], [MachineNumber], [Age]) " +
                        "VALUES (@report ,@reportDescription ,@catalog, @workerName," +
                        " @LastCalibrationDate, @NextCalibrationDate, @machineNumber, @age)";

                    using (OleDbCommand command = new OleDbCommand(query))
                    {
                        command.Parameters.AddWithValue("@report", reportNumber);
                        command.Parameters.AddWithValue("@reportDescription", reportDescription);
                        command.Parameters.AddWithValue("@catalog", catalog);
                        command.Parameters.AddWithValue("@workerName", workerName); 
                        command.Parameters.AddWithValue("@LastCalibrationDate", c.LastCalibrationDate);
                        command.Parameters.AddWithValue("@NextCalibrationDate", c.NextCalibrationDate);
                        command.Parameters.AddWithValue("@machineNumber", machineNumber);
                        command.Parameters.AddWithValue("@age", age);
                        command.Connection = openCon;
                        openCon.Open();
                        int recordsAffected = command.ExecuteNonQuery();
                        openCon.Close();
                    }
                }
            }
        }

    ....
    ....
    METHODS
    .... 

        }
    }

В моей исполняемой программе я использую это так:

У меня есть такие использования: using static DataBaseManager.LocalPulserDBManager;

и в моемкод, который я выполняю таким методом LocalPulserDBManagerInstance.AddDataToLocalHeaderResult(ReportNumber, Date_Description,CatalogNumber, WorkerName, (int)MachineNumber, calibrationForSave, AgeCells);

Одна из моих таблиц базы данных доступа выглядит так: enter image description here

Одна строка в этой таблице выглядит так:enter image description here

50MS это нормальное время выполнения в такой ситуации?Если здесь отсутствует какая-либо информация, пожалуйста, сообщите мне ...

********************* РЕДАКТИРОВАНИЕ **************************

Я изменил свой метод AddDataToLocalHeaderResult, так как первая команда сказала мне, что я получил тот же результат

public  void AddDataToLocalHeaderResult(string reportNumber,string reportDescription, 
            string catalog,string workerName,int machineNumber, Calibration c,string age)
        {
            if (IsHeaderLocalDataExist(reportNumber, catalog, machineNumber, c) == false)
            {
                using (OleDbConnection openCon = new OleDbConnection(localConnectionString))
                {
                    string query = "INSERT into [HeaderResult] ([ReportNumber],[ReportDescription],[CatalogNumber], " +
                        "[WorkerName], [LastCalibrationDate], [NextCalibrationDate], [MachineNumber], [EditTime], [Age]) " +
                        "VALUES (@report ,@reportDescription ,@catalog, @workerName," +
                        " @LastCalibrationDate, @NextCalibrationDate, @machineNumber,@edittime, @age)";
                    DateTime dt = DateTime.Now;
                    DateTime edittime = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);

                    using (OleDbCommand command = new OleDbCommand(query))
                    {
                        command.Parameters.AddWithValue("@report", reportNumber);
                        command.Parameters.AddWithValue("@reportDescription", reportDescription);
                        command.Parameters.AddWithValue("@catalog", catalog);
                        command.Parameters.AddWithValue("@workerName", workerName); 
                        command.Parameters.AddWithValue("@LastCalibrationDate", c.LastCalibrationDate);
                        command.Parameters.AddWithValue("@NextCalibrationDate", c.NextCalibrationDate);
                        command.Parameters.AddWithValue("@machineNumber", machineNumber);
                        command.Parameters.AddWithValue("@edittime", edittime);
                        command.Parameters.AddWithValue("@age", age);
                        command.Connection = openCon;
                        openCon.Open();
                        int recordsAffected = command.ExecuteNonQuery();
                        openCon.Close();
                    }
                }
            }
        }

1 Ответ

1 голос
/ 19 марта 2019

Используя метод, который вы показываете здесь, вы добавляете по одной строке за раз. Таким образом, сервер открывает соединение с БД, данные записываются в память, затем в физический файл (mdb), затем индексы обновляются. Это целых четыре шага в строке, которые вы пытаетесь выполнить. Хуже того, запись данных в физический файл занимает много времени.

Я думаю, что если вы используете другой подход, выполните эти четыре шага (подключение, память, запись данных, переиндексация) для всего набора данных, которые вы пытаетесь вставить. Итак, предположим, что вы добавляете 1000 записей, а не 4000 шагов (4x1000), вы можете сократить эту обработку до 1400 шагов обработки (1 соединение, сверхбыстрая запись в память 1000, 1 запись в файл данных, 1 пересмотр индекса).

Следующий код дает приблизительное представление о том, о чем я говорю:

class Program
{
    static void Main(string[] args)
    {
        //memory-only list for data loading
        List<HeaderResult> mylist = new List<HeaderResult>(){ new HeaderResult("report1","desc of report","ete"), new HeaderResult("report2", "desc of report2", "ete2")};
        var tableForInsert = new DataTable();
        using (SqlDataAdapter dataAdapter = new SqlDataAdapter("SELECT * from  HeaderResult", "my conneciton string")) {
            dataAdapter.Fill(tableForInsert);

            //now I have a live copy of the table into which I want to insert data
            //blast in the data
            foreach (HeaderResult hr in mylist) {
                tableForInsert.Rows.Add(hr);
            }

            //now all the data is written at once and sql will take care of the indexes after the datat's written
            dataAdapter.Update(tableForInsert);
        }
}

//class should have same fields as your table
class HeaderResult
{
    string report;
    string reportDescription;
    string etc;
    public HeaderResult(string rpt, string desc, string e)
    {
        report = rpt;
        reportDescription = desc;
        etc = e;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...