이 글은 기계 번역의 미러 문서이며, 원본 기사로 바로 이동하려면 여기를 클릭해 주세요.

보기: 13193|회답: 0

[팁] 라이브러리 내 자기 증가 필드를 사용하여 Guid 필드의 기본 키의 성능을 비교해 보세요

[링크 복사]
게시됨 2015. 10. 26. 오전 9:37:04 | | | |
1. 개요:

우리 데이터베이스 설계에서는 데이터베이스의 기본 키가 필수적이며, 기본 키의 설계는 전체 데이터베이스 설계에 큰 영향을 미칩니다. 자동 증분 필드와 Guid 필드의 성능을 비교할 것이며, 토론 환영합니다.

2. 소개:

1. 자기 증분 장

      자기 증가 필드는 매번 순차적으로 증가하여 테이블의 주요 키가 반복되지 않도록 합니다. 자기 증가 필드 타입의 최대 값을 초과하거나 처음부터 증가하지 않는 한, 이는 거의 불가능합니다. 자기 증가 필드를 기본 키로 사용하는 것은 매우 간단하며, 보통 테이블을 만들 때 자가 증가 속성을 선언하면 됩니다.

      자가 증가 값은 시스템에서 유지되어야 하는 모든 전역 데이터 값이며, 데이터가 삽입될 때마다 값이 증가합니다. 동시 환경에서는 동등한 값이 고유 정체성을 생성하므로, 각 증분 값은 이 전역 값으로 잠금되고 해제되어야 고유성을 보장합니다. 이것은 성능 문제를 동반하는 병목 현상이 될 수 있습니다.

데이터를 마이그레이션하거나 가져올 때 자가 증분 필드가 중복될 수 있는데, 이는 분명 악몽입니다(저도 이미 겪은 경험이 있습니다).

      분산 데이터베이스를 구축하고 싶다면, 이 자기 증가 필드는 문제가 됩니다. 이는 분산 데이터베이스에서는 서로 다른 데이터베이스에서 같은 이름을 가진 테이블을 동기식으로 복제해야 할 수 있기 때문입니다. 데이터베이스 테이블의 자기 증가 값은 동일한 테이블의 자기 증가 값과 다른 데이터베이스에서 중복될 가능성이 높습니다.

2. 고유식별자(Guid) 필드

MS SQL 데이터베이스에서는 필드 타입을 고유식별자(uniqueidentifier)로 지정하여 테이블 구조를 생성할 수 있으며, NewID()를 사용해 기본 값을 생성하여 고유 Guid(전역 고유 식별자)를 생성할 수 있습니다.

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

GUID의 장점은 생성된 ID가 비교적 고유하다는 점으로, 데이터를 내보내든 단계별 개발이든 문제 없이 진행됩니다. 하지만 생성되는 ID는 비교적 길고, 데이터베이스 공간도 차지되어 있어 외부 저장 비용이 낮아지는 상황에서 이 점을 고려할 필요가 없습니다. 또한 Guid는 기억하기 쉽지 않으며, 이 점에서 자동 증분 필드만큼 좋지 않아 프로그램 디버깅 시 편리하지 않습니다.

3. 테스트:

1. 환경 검사

운영체제: Windows Server 2003 R2 엔터프라이즈 에디션 서비스 팩 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. 데이터를 데이터셋에 읽습니다
테스트 1
읽힌 데이터량: 100
결과를 돌려봐
테스트 2
읽힌 데이터량: 10,000
결과를 돌려봐
테스트 3
읽힌 데이터량: 100,000
결과를 돌려봐
테스트 4
읽힌 데이터량: 500,000
결과를 돌려봐
4. 총 수 검사 기록
검사 결과
5. 조건 쿼리 테스트를 지정한다
쿼리 데이터베이스의 300,000번째 레코드는 610,300입니다.
4. 요약:
Guid를 메인 키로 사용하는 것은 매우 느리진 않지만, 자동 성장 증가 키보다는 빠릅니다.





이전의:asp.net 이진 Base64 콘텐츠를 이미지로 변환하여 로컬에 저장할 수 있습니다
다음:String[3]: Size 속성의 크기가 0입니다.
면책 조항:
Code Farmer Network에서 발행하는 모든 소프트웨어, 프로그래밍 자료 또는 기사는 학습 및 연구 목적으로만 사용됩니다; 위 내용은 상업적 또는 불법적인 목적으로 사용되지 않으며, 그렇지 않으면 모든 책임이 사용자에게 부담됩니다. 이 사이트의 정보는 인터넷에서 가져온 것이며, 저작권 분쟁은 이 사이트와는 관련이 없습니다. 위 내용은 다운로드 후 24시간 이내에 컴퓨터에서 완전히 삭제해야 합니다. 프로그램이 마음에 드신다면, 진짜 소프트웨어를 지원하고, 등록을 구매하며, 더 나은 진짜 서비스를 받아주세요. 침해가 있을 경우 이메일로 연락해 주시기 바랍니다.

Mail To:help@itsvse.com