Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

So sánh hiệu suất SQL Server CE 4.0

Theo ý kiến ​​của tôi, việc so sánh cơ sở dữ liệu nhúng (như SQL CE) với cơ sở dữ liệu quan hệ phía máy chủ là không chính xác (giống như tất cả các phần còn lại, ngoại trừ SQLite và phiên bản Nhúng của Firebird).

Sự khác biệt chính giữa chúng là cơ sở dữ liệu quan hệ phía máy chủ có mục đích chung (như MS SQL, MySQL, Firebird Classic và SuperServer, v.v.) được cài đặt như một dịch vụ độc lập và chạy bên ngoài phạm vi ứng dụng chính của bạn . Đó là lý do tại sao chúng có thể hoạt động tốt hơn nhiều nhờ sự hỗ trợ nội tại cho kiến ​​trúc đa lõi và đa CPU, sử dụng các tính năng của hệ điều hành như bộ nhớ đệm trước, VSS, v.v. để tăng thông lượng trong trường hợp hoạt động cơ sở dữ liệu chuyên sâu và có thể yêu cầu nhiều bộ nhớ như hệ điều hành của bạn có thể cung cấp cho một dịch vụ / ứng dụng duy nhất. Điều đó cũng có nghĩa là các chỉ số hiệu suất cho chúng ít nhiều độc lập với ứng dụng của bạn, nhưng phần lớn phụ thuộc vào phần cứng của bạn. Về mặt này, tôi muốn nói rằng các phiên bản máy chủ của bất kỳ cơ sở dữ liệu nào luôn có hiệu suất cao hơn so với các phiên bản được nhúng.

SQL CE (cùng với Firebird Embedded, SQLite, TurboSQL và một số khác) là công cụ DB được nhúng , nghĩa là cơ sở dữ liệu hoàn chỉnh được đóng gói thành một (hoặc tối đa là 2) tệp DLL được phân phối cùng với ứng dụng của bạn. Do các giới hạn về kích thước rõ ràng (bạn có muốn phải phân phối một tệp DLL 30 MB cùng với ứng dụng dài 2-3 MB của mình không?), Chúng cũng chạy trực tiếp trong ngữ cảnh ứng dụng của bạn và tổng số bộ nhớ và hiệu suất cho các hoạt động truy cập dữ liệu được chia sẻ với các phần khác trong ứng dụng của bạn - liên quan đến cả bộ nhớ khả dụng, thời gian CPU, thông lượng đĩa, v.v. Việc có một luồng tính toán chuyên sâu chạy song song với luồng truy cập dữ liệu của bạn có thể dẫn đến hiệu suất cơ sở dữ liệu của bạn giảm đáng kể.

Do các lĩnh vực ứng dụng khác nhau, các cơ sở dữ liệu này có các bảng tùy chọn khác nhau:server-db cung cấp khả năng quản lý quyền và người dùng rộng rãi, hỗ trợ các chế độ xem và thủ tục được lưu trữ, trong khi cơ sở dữ liệu nhúng thường thiếu bất kỳ hỗ trợ nào cho người dùng và quản lý quyền và có giới hạn hỗ trợ cho các chế độ xem và các thủ tục được lưu trữ (những thủ tục sau mất phần lớn lợi ích của chúng khi chạy trên phía máy chủ). Thông lượng dữ liệu là điểm nghẽn thông thường của RDBMS, các phiên bản máy chủ thường được cài đặt trên các ổ RAID sọc, trong khi DB nhúng thường hướng đến bộ nhớ (cố gắng giữ tất cả dữ liệu thực tế trong bộ nhớ) và giảm thiểu các hoạt động truy cập lưu trữ dữ liệu.

Vì vậy, điều có ý nghĩa có lẽ là so sánh các RDBMS nhúng khác nhau cho .Net về hiệu suất của chúng, như MS SQL CE 4.0, SQLite, Firebird Embedded, TurboSQL . Tôi sẽ không mong đợi sự khác biệt lớn trong quá trình hoạt động không cao điểm thông thường, trong khi một số cơ sở dữ liệu có thể hỗ trợ tốt hơn cho các BLOB lớn do tích hợp tốt hơn với OS.

- cập nhật -

Tôi phải rút lại những lời cuối cùng của mình, vì việc triển khai nhanh chóng của tôi cho thấy những kết quả rất thú vị.

Tôi đã viết một ứng dụng bảng điều khiển ngắn để kiểm tra cả hai nhà cung cấp dữ liệu, đây là mã nguồn dành cho bạn nếu bạn muốn tự mình thử nghiệm với chúng.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;
using System.Data.SqlServerCe;
using System.Data.Common;

namespace TestSQL
{
    class Program
    {
        const int NUMBER_OF_TESTS = 1000;

        private static string create_table;

        private static string create_table_sqlce =  "CREATE TABLE Test ( id integer not null identity primary key, textdata nvarchar(500));";
        private static string create_table_sqlite = "CREATE TABLE Test ( id integer not null primary key, textdata nvarchar(500));";

        private static string drop_table = "DROP TABLE Test";
        private static string insert_data = "INSERT INTO Test (textdata) VALUES ('{0}');";
        private static string read_data = "SELECT textdata FROM Test WHERE id = {0}";
        private static string update_data = "UPDATE Test SET textdata = '{1}' WHERE id = {0}";
        private static string delete_data = "DELETE FROM Test WHERE id = {0}";

        static Action<DbConnection> ACreateTable = (a) => CreateTable(a);
        static Action<DbConnection> ATestWrite = (a) => TestWrite(a, NUMBER_OF_TESTS);
        static Action<DbConnection> ATestRead = (a) => TestRead(a, NUMBER_OF_TESTS);
        static Action<DbConnection> ATestUpdate = (a) => TestUpdate(a, NUMBER_OF_TESTS);
        static Action<DbConnection> ATestDelete = (a) => TestDelete(a, NUMBER_OF_TESTS);
        static Action<DbConnection> ADropTable = (a) => DropTable(a);

        static Func<Action<DbConnection>,DbConnection, TimeSpan> MeasureExecTime = (a,b) => { var start = DateTime.Now; a(b); var finish = DateTime.Now; return finish - start; };

        static Action<string, TimeSpan> AMeasureAndOutput = (a, b) => Console.WriteLine(a, b.TotalMilliseconds);

        static void Main(string[] args)
        {
            // opening databases
            SQLiteConnection.CreateFile("sqlite.db");
            SQLiteConnection sqliteconnect = new SQLiteConnection("Data Source=sqlite.db");
            SqlCeConnection sqlceconnect = new SqlCeConnection("Data Source=sqlce.sdf");

            sqlceconnect.Open();
            sqliteconnect.Open();

            Console.WriteLine("=Testing CRUD performance of embedded DBs=");
            Console.WriteLine(" => Samplesize: {0}", NUMBER_OF_TESTS);

            create_table = create_table_sqlite;
            Console.WriteLine("==Testing SQLite==");
            DoMeasures(sqliteconnect);

            create_table = create_table_sqlce;
            Console.WriteLine("==Testing SQL CE 4.0==");
            DoMeasures(sqlceconnect);



            Console.ReadKey();

        }

        static void DoMeasures(DbConnection con)
        {
            AMeasureAndOutput("Creating table: {0} ms", MeasureExecTime(ACreateTable, con));
            AMeasureAndOutput("Writing data: {0} ms", MeasureExecTime(ATestWrite, con));
            AMeasureAndOutput("Updating data: {0} ms", MeasureExecTime(ATestUpdate, con));
            AMeasureAndOutput("Reading data: {0} ms", MeasureExecTime(ATestRead, con));
            AMeasureAndOutput("Deleting data: {0} ms", MeasureExecTime(ATestDelete, con));
            AMeasureAndOutput("Dropping table: {0} ms", MeasureExecTime(ADropTable, con));
        }



        static void CreateTable(DbConnection con)
        {
            var sqlcmd = con.CreateCommand();
            sqlcmd.CommandText = create_table;
            sqlcmd.ExecuteNonQuery();
        }

        static void TestWrite(DbConnection con, int num)
        {
            for (; num-- > 0; )
            {
                var sqlcmd = con.CreateCommand();
                sqlcmd.CommandText = string.Format(insert_data,Guid.NewGuid().ToString());
                sqlcmd.ExecuteNonQuery();
            }

        }

        static void TestRead(DbConnection con, int num)
        {
            Random rnd = new Random(DateTime.Now.Millisecond);
            for (var max = num; max-- > 0; )
            {
                var sqlcmd = con.CreateCommand();
                sqlcmd.CommandText = string.Format(read_data, rnd.Next(1,num-1));
                sqlcmd.ExecuteNonQuery();
            }
        }

        static void TestUpdate(DbConnection con, int num)
        {
            Random rnd = new Random(DateTime.Now.Millisecond);
            for (var max = num; max-- > 0; )
            {
                var sqlcmd = con.CreateCommand();
                sqlcmd.CommandText = string.Format(update_data, rnd.Next(1, num - 1), Guid.NewGuid().ToString());
                sqlcmd.ExecuteNonQuery();
            }
        }

        static void TestDelete(DbConnection con, int num)
        {
            Random rnd = new Random(DateTime.Now.Millisecond);
            var order = Enumerable.Range(1, num).ToArray<int>();
            Action<int[], int, int> swap = (arr, a, b) => { int c = arr[a]; arr[a] = arr[b]; arr[b] = c; };

            // shuffling the array
            for (var max=num; max-- > 0; ) swap(order, rnd.Next(0, num - 1), rnd.Next(0, num - 1));


            foreach(int index in order)
            {
                var sqlcmd = con.CreateCommand();
                sqlcmd.CommandText = string.Format(delete_data, index);
                sqlcmd.ExecuteNonQuery();
            }
        }

        static void DropTable(DbConnection con)
        {
            var sqlcmd = con.CreateCommand();
            sqlcmd.CommandText = drop_table;
            sqlcmd.ExecuteNonQuery();
        }


    }
}

Tuyên bố từ chối trách nhiệm cần thiết:

  1. Tôi nhận được những kết quả này trên máy của mình: Dell Precision WorkStation T7400 được trang bị 2 CPU Intel Xeon E5420 và 8GB RAM, chạy 64bit Win7 Enterprise .
  2. Tôi đã sử dụng cài đặt mặc định cho cả hai DB với chuỗi kết nối "Nguồn dữ liệu =database_file_name".
  3. Tôi đã sử dụng phiên bản mới nhất của cả SQL CE 4.0 và SQLite / System.Data.SQLite (từ hôm nay, ngày 3 tháng 6 năm 2011).

Đây là kết quả cho hai mẫu khác nhau:

> =Testing CRUD performance of embedded DBs=  
> => Samplesize: 200
> ==Testing SQLite== 
> Creating table: 396.0396 ms 
> Writing data: 22189.2187 ms 
> Updating data: 23591.3589 ms
> Reading data: 21.0021 ms 
> Deleting data: 20963.0961 ms 
> Dropping table: 85.0085 ms

> ==Testing SQL CE 4.0== 
> Creating table: 16.0016 ms 
> Writing data: 25.0025 ms 
> Updating data: 56.0056 ms 
> Reading data: 28.0028 ms 
> Deleting data: 53.0053 ms 
> Dropping table: 11.0011 ms

... và một mẫu lớn hơn:

=Testing CRUD performance of embedded DBs=
 => Samplesize: 1000
==Testing SQLite==
Creating table: 93.0093 ms
Writing data: 116632.6621 ms
Updating data: 104967.4957 ms
Reading data: 134.0134 ms
Deleting data: 107666.7656 ms
Dropping table: 83.0083 ms

==Testing SQL CE 4.0==
Creating table: 16.0016 ms
Writing data: 128.0128 ms
Updating data: 307.0307 ms
Reading data: 164.0164 ms
Deleting data: 306.0306 ms
Dropping table: 13.0013 ms

Vì vậy, như bạn có thể thấy, bất kỳ hoạt động viết nào (tạo, cập nhật, xóa) đòi hỏi thời gian trong SQLite nhiều hơn gần 1000 lần so với SQLCE. Nó không nhất thiết phản ánh hiệu suất kém chung của cơ sở dữ liệu này và có thể do những nguyên nhân sau:

  1. Nhà cung cấp dữ liệu tôi sử dụng cho SQLite là System.Data.SQLite , đó là một assembly hỗn hợp chứa cả mã được quản lý và không được quản lý (SQLite ban đầu được viết hoàn toàn bằng C và DLL chỉ cung cấp các ràng buộc). Có lẽ P / Invoke và dữ liệu sắp xếp phù hợp sẽ tiêu tốn một phần thời gian hoạt động.
  2. Nhiều khả năng SQLCE 4.0 lưu trữ tất cả dữ liệu trong bộ nhớ theo mặc định, trong khi SQLite chuyển hầu hết các thay đổi dữ liệu trực tiếp vào bộ nhớ đĩa mỗi khi thay đổi xảy ra. Người ta có thể cung cấp hàng trăm tham số cho cả hai cơ sở dữ liệu thông qua chuỗi kết nối và điều chỉnh chúng một cách thích hợp.
  3. Tôi đã sử dụng một loạt các truy vấn đơn lẻ để kiểm tra DB. Ít nhất SQLCE hỗ trợ các hoạt động hàng loạt thông qua các lớp .Net đặc biệt sẽ phù hợp hơn ở đây. Nếu SQLite cũng hỗ trợ chúng (xin lỗi, tôi không phải là chuyên gia ở đây và việc tìm kiếm nhanh của tôi không mang lại kết quả gì đầy hứa hẹn), cũng sẽ rất tuyệt khi so sánh chúng.
  4. Tôi đã quan sát thấy nhiều vấn đề với SQLite trên các máy x64 (sử dụng cùng một bộ điều hợp .net):từ việc kết nối dữ liệu bị đóng đột ngột đến lỗi tệp cơ sở dữ liệu. Tôi cho rằng có một số vấn đề về độ ổn định với bộ điều hợp dữ liệu hoặc với chính thư viện.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hiển thị động các hàng dưới dạng cột

  2. Làm cách nào để chỉ chọn mục nhập mới nhất trong bảng?

  3. Hãy thử các phương pháp hay nhất về giám sát cơ sở dữ liệu MySQL này

  4. Sao lưu một bảng duy nhất với dữ liệu của nó từ cơ sở dữ liệu trong sql server 2008

  5. Cách tạo tệp đầu ra csv từ quy trình được lưu trữ trong SQL Server