sqlite sqlitecommand ExecuteNonQuery против ExecuteNonQueryAsyn c c# - PullRequest
0 голосов
/ 14 апреля 2020

Я использую c# sqlite версии 3. Мое приложение требует сохранения до 20 столбцов данных на частоте 4000 Гц. Для достижения sh этого я использую потоки, которые принимают команды из очереди и периодически записывают / читают в базу данных. В настоящее время я просто работаю над частью записи и обнаружил, что ExecuteNonQueryAsyn c () и ExecuteNonQuery () имеют относительно одинаковое время выполнения, что не имеет смысла для меня. Моя функция выглядит следующим образом:

        public async Task<int> dumpStorage(string cmdStr)
        {
            int r;
            using (SQLiteCommand cmd = new SQLiteCommand(sqliteConnection))
            {
                    string times = "";
                    Stopwatch tTime = new Stopwatch();
                    tTime.Start();
                cmd.CommandText = cmdStr;
                    times += "tTime1 " + tTime.Elapsed.Seconds + ":" + tTime.Elapsed.Milliseconds + "\n";
                    tTime.Restart();
                r = await cmd.ExecuteNonQueryAsync();
                //cmd.ExecuteNonQuery();
                //cmd.ExecuteScalar();
                //cmd.ExecuteScalarAsync();
                    times += "tTime2 " + tTime.Elapsed.Seconds + ":" + tTime.Elapsed.Milliseconds + "\n";
                    tTime.Restart();
                transaction.Commit();
                    times += "tTime2 " + tTime.Elapsed.Seconds + ":" + tTime.Elapsed.Milliseconds + "\n";
                    tTime.Restart();
                transaction = sqliteConnection.BeginTransaction();
                    tTime.Stop();
                    times += "tTime3 " + tTime.Elapsed.Seconds + ":" + tTime.Elapsed.Milliseconds + "\n";
                    timeStr = times;
                storeToDBWatchDog.Restart();
            }
            return r;
        }

В настоящий момент я сохраняю 40000 строк с 20 (плюс первичный ключ) столбцами, которые представляют 10 секунд данных. Я не могу заставить asyn c иметь какое-либо преимущество во времени перед функцией non-asyn c. в будущем мне нужно будет ввести схему, которая будет управлять, если возникнут какие-либо ошибки при вставке.

Я ожидаю, что ExecuteNonQueryAsyn c () должен сделать tTime2 практически равным 0, и он будет работать в фоновом режиме, однако это не то, что я вижу, так как кажется, что она ждет завершения функции ... Asyn c ().

для выполнения без запроса asyn c и без asyn c требуется примерно 2,1 секунды. Конечная цель - сохранить данные как минимум в 20 раз быстрее, чем они поступают. Единственный момент, когда это становится очень важным, - это начальная загрузка. Под этим я подразумеваю, что я читаю существующий файл (не в базе данных), а затем сохраняю его в базе данных. так что на данный момент производительность у меня примерно в 4 раза выше. Я имею в виду, что для сохранения файла, состоящего из данных, связанных с 20 минутами, потребуется 5 минут. это кажется невероятно медленным.

типичное время вывода независимо от того, какой вызов функции используется (обе скалярные функции занимают ~ 50% дольше):

enter image description here

Редактировать: я недавно наткнулся на этот печальный пост, в котором, по сути, говорится, что asyn c ничего не делает, поэтому вам следует использовать настройку WAL: https://docs.microsoft.com/en-us/dotnet/standard/data/sqlite/async

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

            connectionString = "Data Source=" + filename + "; Version=3" + "; PRAGMA journal_mode=WAL;";
            sqliteConnection = new SQLiteConnection(connectionString);

Я не видел каких-либо повышений производительности, устанавливая journal_mode в значение WAL.

...