Bisher hatte ich noch keinen Performance-Vergleich zwischen SQL Server Compact 4 und Access (Jet) gefunden.
Deshalb habe ich quick-and-dirty mal ein bisschen was naives zusammen gebaut (siehe unten).
Hier die Ergebnisse:
1 x DELETE FROM Tabelle1:
- SQL CE: 00:00:00.1187228
- Access: 00:00:00.1891944
1 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES ({LOOPCTR}, '{LOOPCTR}'):
- SQL CE: 00:00:00.0332512
- Access: 00:00:00.0804094
10 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES ({LOOPCTR}, '{LOOPCTR}'):
- SQL CE: 00:00:00.3433201
- Access: 00:00:00.8424340
100 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES ({LOOPCTR}, '{LOOPCTR}'):
- SQL CE: 00:00:03.5079310
- Access: 00:00:08.6798789
1000 x INSERT INTO Tabelle1 (Name1, Wert1) VALUES ({LOOPCTR}, '{LOOPCTR}'):
- SQL CE: 00:00:35.8964553
- Access: 00:01:19.2733553
1 x SELECT * FROM Tabelle1:
- SQL CE: 00:00:00.0447322
- Access: 00:00:00.0877710
10 x SELECT * FROM Tabelle1:
- SQL CE: 00:00:00.2697948
- Access: 00:00:00.6747978
100 x SELECT * FROM Tabelle1:
- SQL CE: 00:00:02.4612987
- Access: 00:00:07.9719581
1000 x SELECT * FROM Tabelle1:
- SQL CE: 00:00:26.1076206
- Access: 00:01:11.9598524
In allen Fällen, sowohl bei INSERT
- als auch bei SELECT
-Befehlen war SQL CE deutlich schneller.
({LOOPCTR}
war meine Zählvariable in der Schleife)
Bitte beachtet, dass ich weder JOINs noch ORDER BYs und WHERE-Bedingungen verwendet habe. Damit kann das ggf. nochmals anders aussehen.
Der Quellcode:
internal static class Program
{
private const string Folder = @"C:\Users\ukeim\Dropbox\Beruf\Prog\PerformanceMdbVsSqlCe\PerformanceMdbVsSqlCe";
private static readonly string SqlCeConnectionString = $@"DataSource=""{Folder}\test.sdf""";
private static readonly string MdbConnectionString =
$@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=""{Folder}\test.mdb""";
private static void Main()
{
/*
File.Delete($@"{Folder}\test.sdf");
createDB();
executeSqlCe(
@"CREATE TABLE [Tabelle1] (
[ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
Name1 NVARCHAR(255),
Wert1 [int]
)");
*/
test1(1, @"DELETE FROM Tabelle1");
test1(1, @"INSERT INTO Tabelle1 (Name1, Wert1) VALUES ({LOOPCTR}, '{LOOPCTR}')");
test1(10, @"INSERT INTO Tabelle1 (Name1, Wert1) VALUES ({LOOPCTR}, '{LOOPCTR}')");
test1(100, @"INSERT INTO Tabelle1 (Name1, Wert1) VALUES ({LOOPCTR}, '{LOOPCTR}')");
test1(1000, @"INSERT INTO Tabelle1 (Name1, Wert1) VALUES ({LOOPCTR}, '{LOOPCTR}')");
test1(1, @"SELECT * FROM Tabelle1");
test1(10, @"SELECT * FROM Tabelle1");
test1(100, @"SELECT * FROM Tabelle1");
test1(1000, @"SELECT * FROM Tabelle1");
}
private static void test1(int rowCount, string sql)
{
var sw = new Stopwatch();
// --
Console.WriteLine(@"{0} x {1}:", rowCount, sql);
sw.Start();
for (var i = 0; i < rowCount; i++)
{
executeSqlCe(sql.Replace(@"{LOOPCTR}", i.ToString()));
}
sw.Stop();
Console.WriteLine(@"- SQL CE: {0}", sw.Elapsed);
// --
sw.Start();
for (var i = 0; i < rowCount; i++)
{
executeMdb(sql.Replace(@"{LOOPCTR}", i.ToString()));
}
sw.Stop();
Console.WriteLine(@"- Access: {0}", sw.Elapsed);
Console.WriteLine();
}
private static void createDB()
{
var en = new SqlCeEngine(SqlCeConnectionString);
en.CreateDatabase();
}
private static DataTable executeSqlCe(string sql)
{
using (var conn = new SqlCeConnection(SqlCeConnectionString))
using (var da = new SqlCeDataAdapter(sql, conn))
{
var table = new DataTable();
da.Fill(table);
return table;
}
}
private static DataTable executeMdb(string sql)
{
using (var conn = new OleDbConnection(MdbConnectionString))
using (var da = new OleDbDataAdapter(sql, conn))
{
var table = new DataTable();
da.Fill(table);
return table;
}
}
}
Siehe dazu auch meine ähnliche Frage auf Stack Overflow von 2011. Den gesamten Quelltext meines Programms habe ich jetzt auch auf Pastebin abgelegt.
Außerdem habe ich das ganze jetzt auch um SQLite-Unterstützung erweitert.