• Авторизация


Увеличение скорости записи в SQLite базу. С примером кода на C# 17-12-2009 13:42 к комментариям - к полной версии - понравилось!


Столкнулся с проблемой долгого выполнения большого количества INSERT  в SQLite базу. В результате ниже описанного изменения кода получил увеличение скорости почти в 2 раза.

Гугл не дал внятных примеров, особенно на  .Net, что и вызвало желание написать данный пост, надеюсь, поможет кому-нить от геморроя.
Все под катом, так как не представляет никакого интереса для среднестатистического человека.
Первоначально код выглядел так :
 
if (reader.count > 0)   //некие данные, которые надо записать
                {
                   
                    int iProgress = 0; 
                    beginProgress(reader.count); //ПрогрессБар                 
                    try
                    {
                        using (SQLiteCommand cmd = m_db.createCommand())
                        {
 
                            cmd.CommandText = @"INSERT …..                                VALUES (…..)";
 
                            SQLiteParameter Param = new SQLiteParameter("@name", DbType.Int32);
 
                            cmd.Parameters.Add(Param);// обработкапараметров
……
 
                            cmd.Prepare(); 
 
                            myDataset.myTableRow src = myDataset.myTable.NewRow();
                            while (reader.read(src))
                            {
                               
                              Param.Value = src.gid;
                              goods_gidParam.Value = src[name];
…..
                              cmd.ExecuteNonQuery();                                
 
                             
                                iProgress++;
                                setProgress(iProgress);                             
                              
                            }
                        }
                    }
                    finally
                    {
                        endProgress();
                    }
                }
 
Но 4к-6к итераций данного while  выполнялся 4-6 минут, что не есть хорошо. Изучая особенности SqLite базы выяснилось, что есть некая команда Pragma,  в которой можно задать всякие вкусняшки типа кодировки данных и т д.
В том числе некую синхронизация. Как оказалось, SqLite - редкий параноик и не доверяет командам пользователя, оборачивая каждую из них в отдельную транзакцию, которая ,собствено,  и тормозит весь процесс.
По умолчанию 
 PRAGMA synchronous=Normal что означает:а не поверю я тебе и защитю данные транзакцией.
В результате наш код был изменен
 
if (reader.count > 0)
                {
                   
                    int iProgress = 0;                   
                    beginProgress(reader.count);
                    try
                    {
                        using (SQLiteCommand cmd = m_db.createCommand())
                        {
                            m_db.beginTransaction(); 
                            cmd.CommandText = " PRAGMA synchronous=OFF"; //Все ОК! доверяй этой транзакции
                            cmd.ExecuteNonQuery();
 
                            cmd.CommandText = @"INSERT … VALUES( …)";
 
                            SQLiteParameter Param = new SQLiteParameter("@name", DbType.Int32); //обработа параметров
                               … 
                            cmd.Parameters.Add(Param);
                                ……
 
                            cmd.Prepare(); 
 
                            myDataset.myTableRow src = myDataset.myTable.NewRow();
                            while (reader.read(src))
                            {
                               
                              Param.Value = src.gid;//обработа параметров
                              goods_gidParam.Value = src[name];
 
                              cmd.ExecuteNonQuery();                                 
                                iProgress++;
                                setProgress(iProgress);                             
                              
                            }
                            m_db.commitTransaction();
                        }
                    }
                    finally
                    {
                        endProgress();
                        m_db.cancelTransaction();
                    }
                }
 
О полезностях SQLite читаем на родном сайте
 
вверх^ к полной версии понравилось! в evernote
Комментарии (2):
29-06-2010-20:17 удалить
в самом коде m_db это что у тебя?


Комментарии (2): вверх^

Вы сейчас не можете прокомментировать это сообщение.

Дневник Увеличение скорости записи в SQLite базу. С примером кода на C# | glock63 - Коктейль из пива с тоской | Лента друзей glock63 / Полная версия Добавить в друзья Страницы: раньше»