Ця стаття є дзеркальною статтею машинного перекладу, будь ласка, натисніть тут, щоб перейти до оригінальної статті.

Вид: 13193|Відповідь: 0

[Чайови] Порівняйте продуктивність первинного ключа поля Guid за допомогою самоінкрементального поля в бібліотеці

[Копіювати посилання]
Опубліковано 26.10.2015 09:37:04 | | | |
1. Огляд:

У нашому дизайні бази даних первинний ключ бази даних є необхідним, і дизайн первинного ключа має великий вплив на дизайн усієї бази даних. Я порівняю продуктивність авто-інкрементальних полів і Guid-полів, запросимо обговорити.

2. Вступ:

1. Самоінкрементні поля

      Самоінкрементальні поля додаються послідовно кожного разу, що гарантує, що первинні ключі в таблиці не повторюються. Якщо максимальне значення типу поля з самозбільшенням не буде перевищено і не збільшене з нуля, це майже неможливо. Дуже просто використовувати самоінкрементальні поля як первинні ключі, зазвичай просто вказувати атрибути самоінкрементування при побудові таблиці.

      Самоінкрементні значення — це всі глобальні значення даних, які потрібно підтримувати в системі, і значення збільшується щоразу, коли дані вставляються. У паралельному середовищі, де еквівалент генерує унікальну ідентичність, кожне інкрементальне значення має бути заблоковане та розблоковане з цим глобальним значенням, щоб забезпечити унікальність інкременту. Це може бути паралельним вузьким місцем, що супроводжується певними проблемами продуктивності.

Під час міграції або імпорту даних можуть дублюватися самоінкрементні поля, що, без сумніву, є кошмаром (я вже страждав від цього).

      Якщо ви хочете створити розподілену базу даних, ця самоінкрементальна сфера є проблемою. Це пов'язано з тим, що в розподіленій базі даних таблиці з однаковими назвами з різних баз даних можуть потребувати синхронної реплікації. Самоінкрементальне значення таблиці бази даних, ймовірно, буде дубльоване з самоінкрементним значенням тієї ж таблиці в іншій базі даних.

2. поле унікального ідентифікатора (Guid)

У базах даних MS SQL структуру таблиці можна створити, вказавши тип поля як унікальний ідентифікатор, а її значення за замовчуванням можна згенерувати за допомогою NewID() для генерації унікального Guid (Глобально унікальний ідентифікатор).

Guid:指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,其算法是通过以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字生成。其格式为:04755396-9A29-4B8C-A38D-00042C1B9028.

Перевага GUID у тому, що згенерований ID є відносно унікальним: чи то експорт даних, чи покрокова розробка — проблем не виникне. Однак ID, який він генерує, досить довгий, і простір бази даних також зайнятий, тому це не потрібно враховувати, оскільки вартість зовнішнього сховища знижується. Крім того, Guid важко запам'ятати, і в цьому плані він гірший за автоматичні інкрементні поля, що не дуже зручно при налагодженні програм.

3. Тестування:

1. Протестуйте середовище

Операційна система: Windows Server 2003 R2 Enterprise Edition Service Pack 2

База даних: MS SQL 2005

CPU:Intel(R) Pentium(R) 4 CPU 3.40GHz

Пам'ять: DDRII. 667 1G

Жорсткий диск: WD 80G

2. Скрипти бази даних
  1. --自增量字段表
  2. CREATE TABLE [dbo].[Table_Id](
  3.     [Id] [int] IDENTITY(1,1) NOT NULL,
  4.     [Value] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
  5. CONSTRAINT [PK_Table_Id] PRIMARY KEY CLUSTERED
  6. (
  7.     [Id] ASC
  8. )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
  9. ) ON [PRIMARY]

  10. GO
  11. --Guid字段表
  12. CREATE TABLE [dbo].[Table_Guid](
  13.     [Guid] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Table_Guid_Guid]  DEFAULT (newid()),
  14.     [Value] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
  15. CONSTRAINT [PK_Table_Guid] PRIMARY KEY CLUSTERED
  16. (
  17.     [Guid] ASC
  18. )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
  19. ) ON [PRIMARY]

  20. GO
Копія коду
Тестовий код
  1. 1using System;
  2.   2using System.Collections.Generic;
  3.   3using System.Text;
  4.   4using System.Data.SqlClient;
  5.   5using System.Diagnostics;
  6.   6using System.Data;
  7.   8namespace GuidTest
  8.   9{
  9.    class Program
  10.    {
  11.        string Connnection = "server=.;database=GuidTest;Integrated Security=true;";
  12.        static void Main(string[] args)
  13.        {
  14.            Program app = new Program();
  15.            int Count = 10000;
  16.            Console.WriteLine("数据记录数为{0}",Count);
  17.            //自动id增长测试;
  18.            Stopwatch WatchId = new Stopwatch();
  19.            Console.WriteLine("自动增长id测试");
  20.            Console.WriteLine("开始测试");
  21.            WatchId.Start();
  22.            Console.WriteLine("测试中");
  23. 25            app.Id_InsertTest(Count);
  24.            //app.Id_ReadToTable(Count);
  25.            //app.Id_Count();
  26. 29            //查询第300000条记录;
  27.            //app.Id_SelectById();
  28. 32            WatchId.Stop();
  29.            Console.WriteLine("时间为{0}毫秒",WatchId.ElapsedMilliseconds);
  30.            Console.WriteLine("测试结束");
  31. 36            Console.WriteLine("-----------------------------------------");
  32.            //Guid测试;
  33.            Console.WriteLine("Guid测试");
  34.            Stopwatch WatchGuid = new Stopwatch();
  35.            Console.WriteLine("开始测试");
  36.            WatchGuid.Start();
  37.            Console.WriteLine("测试中");
  38. 44            app.Guid_InsertTest(Count);
  39.            //app.Guid_ReadToTable(Count);
  40.            //app.Guid_Count();
  41. 48            //查询第300000条记录;
  42.            //app.Guid_SelectById();
  43. 51            WatchGuid.Stop();
  44.            Console.WriteLine("时间为{0}毫秒", WatchGuid.ElapsedMilliseconds);
  45.            Console.WriteLine("测试结束");
  46.            Console.Read();
  47.        }
  48. 57        /**////
  49.        /// 自动增长id测试
  50.        ///
  51.        private void Id_InsertTest(int count)
  52.        {
  53.            string InsertSql="insert into Table_Id ([Value]) values ({0})";
  54.            using (SqlConnection conn = new SqlConnection(Connnection))
  55.            {
  56.                conn.Open();
  57.                SqlCommand com = new SqlCommand();
  58.                for (int i = 0; i < count; i++)
  59.                {
  60.                    com.Connection = conn;
  61.                    com.CommandText = string.Format(InsertSql, i);
  62.                    com.ExecuteNonQuery();
  63.                }
  64.            }
  65.        }
  66. 76        /**////
  67.        /// 将数据读到Table
  68.        ///
  69.        private void Id_ReadToTable(int count)
  70.        {
  71.            string ReadSql = "select top " + count.ToString() + " * from Table_Id";
  72.            using (SqlConnection conn = new SqlConnection(Connnection))
  73.            {
  74.                SqlCommand com = new SqlCommand(ReadSql, conn);
  75.                SqlDataAdapter adapter = new SqlDataAdapter(com);
  76.                DataSet ds = new DataSet();
  77.                adapter.Fill(ds);
  78.                Console.WriteLine("数据记录数为:{0}", ds.Tables[0].Rows.Count);
  79.            }
  80.        }
  81. 92        /**////
  82.        /// 数据记录行数测试
  83.        ///
  84.        private void Id_Count()
  85.        {
  86.            string ReadSql = "select Count(*) from Table_Id";
  87.            using (SqlConnection conn = new SqlConnection(Connnection))
  88.            {
  89.                SqlCommand com = new SqlCommand(ReadSql, conn);
  90.                conn.Open();
  91.                object CountResult = com.ExecuteScalar();
  92.                conn.Close();
  93.                Console.WriteLine("数据记录数为:{0}",CountResult);
  94.            }
  95.        }
  96. 108        /**////
  97.        /// 根据id查询;
  98.        ///
  99.        private void Id_SelectById()
  100.        {
  101.            string ReadSql = "select * from Table_Id where Id="+300000;
  102.            using (SqlConnection conn = new SqlConnection(Connnection))
  103.            {
  104.                SqlCommand com = new SqlCommand(ReadSql, conn);
  105.                conn.Open();
  106.                object IdResult = com.ExecuteScalar();
  107.                Console.WriteLine("Id为{0}", IdResult);
  108.                conn.Close();
  109.            }
  110.        }
  111.       
  112.        /**////
  113.        /// Guid测试;
  114.        ///
  115.        private void Guid_InsertTest(int count)
  116.        {
  117.            string InsertSql = "insert into Table_Guid ([Value]) values ({0})";
  118.            using (SqlConnection conn = new SqlConnection(Connnection))
  119.            {
  120.                conn.Open();
  121.                SqlCommand com = new SqlCommand();
  122.                for (int i = 0; i < count; i++)
  123.                {
  124.                    com.Connection = conn;
  125.                    com.CommandText = string.Format(InsertSql, i);
  126.                    com.ExecuteNonQuery();
  127.                }
  128.            }
  129.        }
  130. 143        /**////
  131.        /// Guid格式将数据库读到Table
  132.        ///
  133.        private void Guid_ReadToTable(int count)
  134.        {
  135.            string ReadSql = "select top "+count.ToString()+" * from Table_GuID";
  136.            using (SqlConnection conn = new SqlConnection(Connnection))
  137.            {
  138.                SqlCommand com = new SqlCommand(ReadSql, conn);
  139.                SqlDataAdapter adapter = new SqlDataAdapter(com);
  140.                DataSet ds = new DataSet();
  141.                adapter.Fill(ds);
  142.                Console.WriteLine("数据记录为:{0}", ds.Tables[0].Rows.Count);
  143.            }
  144.        }
  145. 159        /**////
  146.        /// 数据记录行数测试
  147.        ///
  148.        private void Guid_Count()
  149.        {
  150.            string ReadSql = "select Count(*) from Table_Guid";
  151.            using (SqlConnection conn = new SqlConnection(Connnection))
  152.            {
  153.                SqlCommand com = new SqlCommand(ReadSql, conn);
  154.                conn.Open();
  155.                object CountResult = com.ExecuteScalar();
  156.                conn.Close();
  157.                Console.WriteLine("数据记录为:{0}", CountResult);
  158.            }
  159.        }
  160. 175        /**////
  161.        /// 根据Guid查询;
  162.        ///
  163.        private void Guid_SelectById()
  164.        {
  165.            string ReadSql = "select * from Table_Guid where Guid='C1763624-036D-4DB9-A1E4-7E16318C30DE'";
  166.            using (SqlConnection conn = new SqlConnection(Connnection))
  167.            {
  168.                SqlCommand com = new SqlCommand(ReadSql, conn);
  169.                conn.Open();
  170.                object IdResult = com.ExecuteScalar();
  171.                Console.WriteLine("Guid为{0}", IdResult);
  172.                conn.Close();
  173.            }
  174.        }
  175.    }
  176. 192}
  177. 193
Копія коду
3. Тест вставки бази даних
Тест 1
Обсяг бази даних: 100 елементів
Запустіть результат
Тест 2
Обсяг бази даних: 10 000 елементів
Запустіть результат

Тест 3
Обсяг бази даних: 100 000 елементів
Запустіть результат
Тест 4
Обсяг бази даних: 500 000 елементів
Запустіть результат
4. Зачитати дані у DataSet
Тест 1
Кількість прочитаних даних: 100
Запустіть результат
Тест 2
Обсяг прочитаних даних: 10 000
Запустіть результат
Тест 3
Обсяг прочитаних даних: 100 000
Запустіть результат
Тест 4
Обсяг прочитаних даних: 500 000
Запустіть результат
4. Зафіксуйте тест загальної кількості
Результати тестів
5. Вкажіть тест запиту до умови
300 000-й запис у базі запитів — 610 300.
4. Резюме:
Використання Guid як основного ключа не дуже повільно, але швидше, ніж автоматичне зростання інкрементів.





Попередній:asp.net конвертувати бінарний контент Base64 у зображення та зберігати їх локально
Наступний:Рядок[3]: властивість Size має недопустимий розмір 0.
Застереження:
Усе програмне забезпечення, програмні матеріали або статті, опубліковані Code Farmer Network, призначені лише для навчання та досліджень; Вищезазначений контент не повинен використовуватися в комерційних чи незаконних цілях, інакше користувачі несуть усі наслідки. Інформація на цьому сайті надходить з Інтернету, і спори щодо авторських прав не мають до цього сайту. Ви повинні повністю видалити вищезазначений контент зі свого комп'ютера протягом 24 годин після завантаження. Якщо вам подобається програма, будь ласка, підтримуйте справжнє програмне забезпечення, купуйте реєстрацію та отримайте кращі справжні послуги. Якщо є будь-яке порушення, будь ласка, зв'яжіться з нами електронною поштою.

Mail To:help@itsvse.com