Questo articolo è un articolo speculare di traduzione automatica, clicca qui per saltare all'articolo originale.

Vista: 13193|Risposta: 0

[Consigli] Confronta la performance della chiave primaria del campo Guid usando il campo auto-incrementale nella libreria

[Copiato link]
Pubblicato su 26/10/2015 09:37:04 | | | |
1. Panoramica:

Nel nostro design del database, la chiave primaria del database è essenziale, e la progettazione della chiave primaria ha un grande impatto sulla progettazione dell'intero database. Confronterò le prestazioni dei campi auto-incrementali e dei campi Guida, benvenuti a discutere.

2. Introduzione:

1. Campi auto-incrementali

      I campi auto-incrementali vengono incrementati in modo sequenziale ogni volta, assicurando che le chiavi primarie di una tabella non vengano ripetute. A meno che il valore massimo del tipo di campo auto-incrementante non venga superato e incrementato da zero, ciò è quasi impossibile. È molto semplice usare campi auto-incrementali come chiavi primarie, generalmente dichiarare semplicemente attributi auto-incrementanti quando si costruisce una tabella.

      I valori auto-incrementali sono tutti valori globali dei dati che devono essere mantenuti nel sistema, e il valore viene incrementato ogni volta che i dati vengono inseriti. In un ambiente concorrente in cui l'equivalente genera un'identità unica, ogni valore incrementale deve essere bloccato e sbloccato con questo valore globale per garantire l'unicità dell'incremento. Questo può rappresentare un collo di bottiglia che comporta alcuni problemi di prestazioni.

Quando si migra o si importano dati, i campi auto-incrementali possono essere duplicati, il che è senza dubbio un incubo (ne ho già sofferto).

      Se vuoi costruire un database distribuito, questo campo auto-incrementale è un problema. Questo perché in un database distribuito, le tabelle con lo stesso nome provenienti da database diversi possono dover essere replicate in modo sincrono. Il valore auto-incrementale di una tabella di database è probabile che venga duplicato con il valore auto-incrementale della stessa tabella in un altro database.

2. campo uniidentificatore (Guid)

Nei database MS SQL, la struttura della tabella può essere creata specificando il tipo di campo come identificatore unico, e il suo valore predefinito può essere generato usando NewID() per generare un Guid unico (Identificatore Unico Globale).

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

Il vantaggio del GUID è che l'ID generato è relativamente unico, che si tratti di esportare dati o di sviluppare passo dopo passo, non ci saranno problemi. Tuttavia, l'ID che genera è relativamente lungo e lo spazio del database è occupato, quindi non c'è bisogno di considerare questo perché il costo dello storage esterno diminuisce. Inoltre, Guid non è facile da ricordare e, sotto questo aspetto, non è efficace come i campi incrementali automatici, che non sono molto comodi per il debug dei programmi.

3. Test:

1. Testare l'ambiente

Sistema operativo: Windows Server 2003 R2 Enterprise Edition Service Pack 2

Database: MS SQL 2005

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

Memoria: DDRII. 667 1G

Hard disk: WD 80G

2. Script di database
  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
Copia codice
Codice di prova
  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
Copia codice
3. Test di inserimento nel database
Test 1
Il volume del database è: 100 elementi
Esegui il risultato
Test 2
Il volume del database è: 10.000 elementi
Esegui il risultato

Test 3
Il volume del database è: 100.000 elementi
Esegui il risultato
Test 4
Il volume del database è: 500.000 elementi
Esegui il risultato
4. Leggere i dati nel DataSet
Test 1
Quantità di dati letti: 100
Esegui il risultato
Test 2
Quantità di dati letti: 10.000
Esegui il risultato
Test 3
Quantità di dati letti: 100.000
Esegui il risultato
Test 4
Quantità di dati letti: 500.000
Esegui il risultato
4. Registrare il numero totale del test
Risultati dei test
5. Specificare il test di query di condizione
Il 300.000° record nel database delle query è 610.300.
4. Sommario:
Usare Guid come chiave principale non è molto lento, ma è più veloce rispetto all'uso di incrementi a crescita automatica.





Precedente:asp.net convertire contenuti binari Base64 in immagini e memorizzarli localmente
Prossimo:Stringa[3]: la proprietà Size ha una dimensione invalida pari a 0.
Disconoscimento:
Tutto il software, i materiali di programmazione o gli articoli pubblicati dalla Code Farmer Network sono destinati esclusivamente all'apprendimento e alla ricerca; I contenuti sopra elencati non devono essere utilizzati per scopi commerciali o illegali, altrimenti gli utenti dovranno sostenere tutte le conseguenze. Le informazioni su questo sito provengono da Internet, e le controversie sul copyright non hanno nulla a che fare con questo sito. Devi eliminare completamente i contenuti sopra elencati dal tuo computer entro 24 ore dal download. Se ti piace il programma, ti preghiamo di supportare software autentico, acquistare la registrazione e ottenere servizi autentici migliori. In caso di violazione, vi preghiamo di contattarci via email.

Mail To:help@itsvse.com