Este artículo es un artículo espejo de traducción automática, por favor haga clic aquí para saltar al artículo original.

Vista: 13193|Respuesta: 0

[Consejos] Compara el rendimiento de la clave primaria del campo Guid usando el campo autoincremental en la biblioteca

[Copiar enlace]
Publicado en 26/10/2015 9:37:04 | | | |
1. Resumen:

En nuestro diseño de bases de datos, la clave primaria de la base de datos es esencial, y el diseño de la clave primaria tiene un gran impacto en el diseño de toda la base de datos. Voy a comparar el rendimiento de campos autoincrementales y de campos GUY, bienvenido a debatir.

2. Introducción:

1. Campos autoincrementales

      Los campos autoincrementales se incrementan secuencialmente cada vez, asegurando que las claves primarias de una tabla no se repitan. A menos que se supere e incremente el valor máximo del tipo de campo autoincrementante desde cero, esto es casi imposible. Es muy sencillo usar campos auto-incrementales como claves primarias, generalmente solo declarar atributos auto-incrementantes al construir una tabla.

      Los valores auto-incrementales son todos valores globales de datos que deben mantenerse en el sistema, y el valor se incrementa cada vez que se insertan los datos. En un entorno concurrente donde el equivalente genera una identidad única, cada valor incremental debe bloquearse y desbloquearse con este valor global para asegurar la unicidad del incremento. Esto puede ser un cuello de botella concurrente que implica algunos problemas de rendimiento.

Al migrar o importar datos, los campos auto-incrementales pueden duplicarse, lo cual sin duda es una pesadilla (yo ya lo he sufrido).

      Si quieres construir una base de datos distribuida, este campo autoincremental es un problema. Esto se debe a que, en una base de datos distribuida, las tablas con el mismo nombre de diferentes bases de datos pueden necesitar replicarse de forma sincrónica. El valor autoincremental de una tabla de base de datos probablemente se duplicará con el valor autoincremental de la misma tabla en otra base de datos.

2. campo Identificador único (Guid)

En bases de datos MS SQL, la estructura de la tabla puede crearse especificando el tipo de campo como identificador único, y su valor predeterminado puede generarse usando NewID() para generar un Guid único (Identificador Globalmente Único).

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

La ventaja del GUID es que el ID generado es relativamente único, ya sea exportando datos o haciendo desarrollo paso a paso, no habrá problemas. Sin embargo, el ID que genera es relativamente largo y el espacio de la base de datos también está ocupado, por lo que no hay necesidad de tener esto en cuenta ya que el precio del almacenamiento externo disminuye. Además, Guid no es fácil de recordar y, en este sentido, no es tan bueno como los campos incrementales automáticos, lo cual no es muy conveniente al depurar programas.

3. Pruebas:

1. Probar el entorno

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

Base de datos: MS SQL 2005

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

Memoria: DDRII. 667 1G

Disco duro: WD 80G

2. Scripts de base de datos
  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
Copiar código
Código de prueba
  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
Copiar código
3. Prueba de inserción de bases de datos
Test 1
El volumen de la base de datos es: 100 elementos
Ejecuta el resultado
Test 2
El volumen de la base de datos es: 10.000 elementos
Ejecuta el resultado

Test 3
El volumen de la base de datos es: 100.000 elementos
Ejecuta el resultado
Test 4
El volumen de la base de datos es: 500.000 elementos
Ejecuta el resultado
4. Leer los datos en el DataSet
Test 1
Cantidad de datos leídos: 100
Ejecuta el resultado
Test 2
Cantidad de datos leídos: 10.000
Ejecuta el resultado
Test 3
Cantidad de datos leídos: 100.000
Ejecuta el resultado
Test 4
Cantidad de datos leídos: 500.000
Ejecuta el resultado
4. Registrar la prueba total de números
Resultados de las pruebas
5. Especificar la prueba de consulta de condición
El registro número 300.000 en la base de datos de consultas es 610.300.
4. Resumen:
Usar Guid como clave principal no es muy lento, pero es más rápido que usar incrementos de crecimiento automático.





Anterior:asp.net convertir contenido binario de Base64 en imágenes y almacenarlo localmente
Próximo:Cadena[3]: la propiedad Size tiene un tamaño inválido de 0.
Renuncia:
Todo el software, materiales de programación o artículos publicados por Code Farmer Network son únicamente para fines de aprendizaje e investigación; El contenido anterior no se utilizará con fines comerciales o ilegales; de lo contrario, los usuarios asumirán todas las consecuencias. La información de este sitio proviene de Internet, y las disputas de derechos de autor no tienen nada que ver con este sitio. Debes eliminar completamente el contenido anterior de tu ordenador en un plazo de 24 horas desde la descarga. Si te gusta el programa, por favor apoya el software genuino, compra el registro y obtén mejores servicios genuinos. Si hay alguna infracción, por favor contáctanos por correo electrónico.

Mail To:help@itsvse.com