SQLiteConnection對象初始化、打開及關閉,其花費時間約為109ms,因此,最好不要頻繁地將該對象初始化、打開與關閉
無論是執行插入或查詢操作,使用事務比不使用事務快,尤其是在批量插入操作時,減少得時間非常明顯
不能每次執行一條SQL語句前開始事務並在SQL語句執行之后提交事務,這樣的執行效率同樣是很慢,最好的情況下,是在開始事務后批量執行SQL語句,再提交事務,這樣的效率是最高的。
SQLiteConnection connection = Run(() => new SQLiteConnection("Data Source = /DB/Test.db"), "連接對象初始化");
Run(() => connection.Open(), "打開連接");
SQLiteCommand command = Run(() => new SQLiteCommand(connection), "命令對象初始化");
#region 執行DELETE命令及收縮數據庫 目前收縮數據庫有問題
//Run(() =>
//{
// //command.CommandText = $"DELETE FROM Info;VACUUM;UPDATE sqlite_sequence SET seq ='0' where name ='Info';";
// command.CommandText = $"DELETE FROM Info;";
// command.ExecuteNonQuery();
//}, "執行DELETE命令及收縮數據庫");
#endregion
#region [---不使用事務---]事務執行INSERT命令
//Run(() =>
//{
// try
// {
// //'A{i:000}' 保留幾位數
// for (int i = 0; i < 1000; i++)
// {
// command.CommandText = $"INSERT INTO Info(Name, Age) VALUES ('A{i:000}','{i}')";
// command.ExecuteNonQuery();
// }
// command.ExecuteScalar();
// }
// catch (Exception ex)
// {
// }
// finally
// {
// }
//}, "[---使用事務---]事務執行INSERT命令");
#endregion
#region [---不使用事務---]使用ExecuteReader方式執行SELECT命令
//List<Test> list1 = Run(() =>
//{
// command.CommandText = $"SELECT * FROM Info";
// List<Test> tests = new List<Test>();
// SQLiteDataReader reader = command.ExecuteReader();
// while (reader.Read())
// {
// Test t = new Test
// {
// Name = (string)reader[0],
// Age = (string)reader[1]
// };
// tests.Add(t);
// }
// reader.Close();
// return tests;
//}, "[---不使用事務---]使用ExecuteReader方式執行SELECT命令");
#endregion
#region [---不使用事務---]使用Fill Table方式執行SELECT命令
//DataTable table1 = Run(() =>
//{
// command.CommandText = $"SELECT * FROM Info";
// SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
// DataTable _table = new DataTable();
// adapter.Fill(_table);
// return _table;
//}, "[---不使用事務---]使用Fill Table方式執行SELECT命令");
#endregion
#region 執行DELETE命令及收縮數據庫 目前收縮數據庫有問題
//sqlite_sequence表也是SQLite的系統表。該表用來保存其他表的RowID的最大值。數據庫被創建時,sqlite_sequence表會被自動創建。
//該表包括兩列。第一列為name,用來存儲表的名稱。第二列為seq,用來保存表對應的RowID的最大值。該值最大值為9223372036854775807。
//當對應的表增加記錄,該表會自動更新。當表刪除,該表對應的記錄也會自動刪除。如果該值超過最大值,會引起SQL_FULL錯誤。所以,
//一旦發現該錯誤,用戶不僅要檢查SQLite文件所在的磁盤空間是否不足,還需要檢查是否有表的ROWID達到最大值。
Run(() =>
{
//sqlite3 收縮數據庫命令vacuum
//INSERT INTO Info(Name, Age) VALUES ('A1000','1')
//command.CommandText = $"DELETE FROM Info;VACUUM;UPDATE sqlite_sequence SET seq ='0' where name ='Info';";
//無法執行UPDATE sqlite_sequence SET seq ='0' where name ='Info' 會提示沒有找到該表
command.CommandText = $"DELETE FROM Info;VACUUM;";
command.ExecuteNonQuery();
}, "執行DELETE命令及收縮數據庫");
#endregion
#region [---使用事務---]執行INSERT命令
SQLiteTransaction transaction = Run(() => connection.BeginTransaction(), "開始事務");
Run(() =>
{
for (int i = 0; i < 3000; i++)
{
command.CommandText = $"INSERT INTO Info(Name, Age) VALUES ('A{i:0000}','{i}')";
command.ExecuteNonQuery();
}
var result = command.ExecuteScalar();
}, "[---使用事務---]執行INSERT命令");
#endregion
#region [---使用事務---]使用ExecuteReader方式執行SELECT命令
List<Test> list2 = Run(() =>
{
command.CommandText = $"SELECT * FROM Info";
List<Test> tests = new List<Test>();
SQLiteDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Test t = new Test
{
Name = (string)reader[0],
Age = (string)reader[1]
};
tests.Add(t);
}
reader.Close();
return tests;
}, "[---使用事務---]使用ExecuteReader方式執行SELECT命令");
#endregion
#region [---使用事務---]使用Fill Table方式執行SELECT命令
DataTable table2 = Run(() =>
{
command.CommandText = $"SELECT * FROM Info";
SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
DataTable _table = new DataTable();
adapter.Fill(_table);
return _table;
}, "[---使用事務---]使用Fill Table方式執行SELECT命令");
#endregion
Run(() => transaction.Commit(), "提交事務");
Run(() => connection.Close(), "關閉連接");
public static void Run(Action action, string description)
{
Stopwatch sw = Stopwatch.StartNew();
action();
Console.WriteLine($"--> {description}: {sw.ElapsedMilliseconds}ms");
}
public static T Run<T>(Func<T> func, string description)
{
Stopwatch sw = Stopwatch.StartNew();
T result = func();
Console.WriteLine($"--> {description}: {sw.ElapsedMilliseconds}ms");
return result;
}