您的位置:首页 > 产品设计 > UI/UE

自增量字段与Guid字段主键的性能对比

2016-01-18 13:51 507 查看
数据库中使用自增量字段与Guid字段主键的性能对比
1.概述:
  在我们的数据库设计中,数据库的主键是必不可少的,主键的设计对整个数据库的设计影响很大.我就对自动增量字段与Guid字段的性能作一下对比,欢迎大家讨论.
2.简介:
  1.自增量字段
      自增量字段每次都会按顺序递增,可以保证在一个表里的主键不重复。除非超出了自增字段类型的最大值并从头递增,但这几乎不可能。使用自增量字段来做主键是非常简单的,一般只需在建表时声明自增属性即可。
      自增量的值都是需要在系统中维护一个全局的数据值,每次插入数据时即对此次值进行增量取值。当在当量产生唯一标识的并发环境中,每次的增量取值都必须最此全局值加锁解锁以保证增量的唯一性。这可能是一个并发的瓶颈,会牵扯一些性能问题。
  在数据库迁移或者导入数据的时候自增量字段有可能会出现重复,这无疑是一场恶梦(本人已经深受其害).
      如果要搞分布式数据库的话,这自增量字段就有问题了。因为,在分布式数据库中,不同数据库的同名的表可能需要进行同步复制。一个数据库表的自增量值,就很可能与另一数据库相同表的自增量值重复了。
  2.uniqueidentifier(Guid)字段
   在MS Sql 数据库中可以在建立表结构是指定字段类型为uniqueidentifier,并且其默认值可以使用NewID()来生成唯一的Guid(全局唯一标识 符).使用NewID生成的比较随机,如果是SQL 2005可以使用NewSequentialid()来顺序生成,在此为了兼顾使用SQL 2000使用了NewID().
  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
  内存:DDRⅡ 667  1G
  硬盘:WD 80G
  2.数据库脚本  


--自增量字段表


CREATE TABLE [dbo].[Table_Id](


    [Id] [int] IDENTITY(1,1) NOT NULL,


    [Value] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,


 CONSTRAINT [PK_Table_Id] PRIMARY KEY CLUSTERED 


(


    [Id] ASC


)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]


) ON [PRIMARY]




GO


--Guid字段表


CREATE TABLE [dbo].[Table_Guid](


    [Guid] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Table_Guid_Guid]  DEFAULT (newid()),


    [Value] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,


 CONSTRAINT [PK_Table_Guid] PRIMARY KEY CLUSTERED 


(


    [Guid] ASC


)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]


) ON [PRIMARY]




GO
 
  测试代码  
  1

using System;
  2

using System.Collections.Generic;
  3

using System.Text;
  4

using System.Data.SqlClient;
  5

using System.Diagnostics;
  6

using System.Data;
  7


  8

namespace GuidTest
  9

{
 10

    class Program
 11

    { 
 12

        string Connnection = "server=.;database=GuidTest;Integrated Security=true;";
 13

        static void Main(string[] args)
 14

        {
 15

            Program app = new Program();
 16

            int Count = 10000;
 17

            Console.WriteLine("数据记录数为{0}",Count);
 18

            //自动id增长测试;
 19

            Stopwatch WatchId = new Stopwatch();
 20

            Console.WriteLine("自动增长id测试");
 21

            Console.WriteLine("开始测试");
 22

            WatchId.Start();
 23

            Console.WriteLine("测试中

");
 24


 25

            app.Id_InsertTest(Count);
 26

            //app.Id_ReadToTable(Count);
 27

            //app.Id_Count();
 28


 29

            //查询第300000条记录;
 30

            //app.Id_SelectById();
 31


 32

            WatchId.Stop();
 33

            Console.WriteLine("时间为{0}毫秒",WatchId.ElapsedMilliseconds);
 34

            Console.WriteLine("测试结束");
 35


 36

            Console.WriteLine("-----------------------------------------");
 37

            //Guid测试;
 38

            Console.WriteLine("Guid测试");
 39

            Stopwatch WatchGuid = new Stopwatch();
 40

            Console.WriteLine("开始测试");
 41

            WatchGuid.Start();
 42

            Console.WriteLine("测试中

");
 43


 44

            app.Guid_InsertTest(Count);
 45

            //app.Guid_ReadToTable(Count);
 46

            //app.Guid_Count();
 47


 48

            //查询第300000条记录;
 49

            //app.Guid_SelectById();
 50


 51

            WatchGuid.Stop();
 52

            Console.WriteLine("时间为{0}毫秒", WatchGuid.ElapsedMilliseconds);
 53

            Console.WriteLine("测试结束");
 54

            Console.Read();
 55

        }
 56


 57

        /// <summary>
 58

        /// 自动增长id测试
 59

        /// </summary>
 60

        private void Id_InsertTest(int count)
 61

        {
 62

            string InsertSql="insert into Table_Id ([Value]) values ({0})";
 63

            using (SqlConnection conn = new SqlConnection(Connnection))
 64

            {
 65

                conn.Open();
 66

                SqlCommand com = new SqlCommand();
 67

                for (int i = 0; i < count; i++)
 68

                {
 69

                    com.Connection = conn;
 70

                    com.CommandText = string.Format(InsertSql, i);
 71

                    com.ExecuteNonQuery();
 72

                }
 73

            }
 74

        }
 75


 76

        /// <summary>
 77

        /// 将数据读到Table
 78

        /// </summary>
 79

        private void Id_ReadToTable(int count)
 80

        {
 81

            string ReadSql = "select top " + count.ToString() + " * from Table_Id";
 82

            using (SqlConnection conn = new SqlConnection(Connnection))
 83

            {
 84

                SqlCommand com = new SqlCommand(ReadSql, conn);
 85

                SqlDataAdapter adapter = new SqlDataAdapter(com);
 86

                DataSet ds = new DataSet();
 87

                adapter.Fill(ds);
 88

                Console.WriteLine("数据记录数为:{0}", ds.Tables[0].Rows.Count);
 89

            }
 90

        }
 91


 92

        /// <summary>
 93

        /// 数据记录行数测试
 94

        /// </summary>
 95

        private void Id_Count()
 96

        {
 97

            string ReadSql = "select Count(*) from Table_Id";
 98

            using (SqlConnection conn = new SqlConnection(Connnection))
 99

            {
100

                SqlCommand com = new SqlCommand(ReadSql, conn);
101

                conn.Open();
102

                object CountResult = com.ExecuteScalar();
103

                conn.Close();
104

                Console.WriteLine("数据记录数为:{0}",CountResult);
105

            }
106

        }
107


108

        /// <summary>
109

        /// 根据id查询;
110

        /// </summary>
111

        private void Id_SelectById()
112

        {
113

            string ReadSql = "select * from Table_Id where Id="+300000;
114

            using (SqlConnection conn = new SqlConnection(Connnection))
115

            {
116

                SqlCommand com = new SqlCommand(ReadSql, conn);
117

                conn.Open();
118

                object IdResult = com.ExecuteScalar();
119

                Console.WriteLine("Id为{0}", IdResult);
120

                conn.Close();
121

            }
122

        }
123

        
124

        /// <summary>
125

        /// Guid测试;
126

        /// </summary>
127

        private void Guid_InsertTest(int count)
128

        {
129

            string InsertSql = "insert into Table_Guid ([Value]) values ({0})";
130

            using (SqlConnection conn = new SqlConnection(Connnection))
131

            {
132

                conn.Open();
133

                SqlCommand com = new SqlCommand();
134

                for (int i = 0; i < count; i++)
135

                {
136

                    com.Connection = conn;
137

                    com.CommandText = string.Format(InsertSql, i);
138

                    com.ExecuteNonQuery();
139

                }
140

            }
141

        }
142


143

        /// <summary>
144

        /// Guid格式将数据库读到Table
145

        /// </summary>
146

        private void Guid_ReadToTable(int count)
147

        {
148

            string ReadSql = "select top "+count.ToString()+" * from Table_GuID";
149

            using (SqlConnection conn = new SqlConnection(Connnection))
150

            {
151

                SqlCommand com = new SqlCommand(ReadSql, conn);
152

                SqlDataAdapter adapter = new SqlDataAdapter(com);
153

                DataSet ds = new DataSet();
154

                adapter.Fill(ds);
155

                Console.WriteLine("数据记录为:{0}", ds.Tables[0].Rows.Count);
156

            }
157

        }
158


159

        /// <summary>
160

        /// 数据记录行数测试
161

        /// </summary>
162

        private void Guid_Count()
163

        {
164

            string ReadSql = "select Count(*) from Table_Guid";
165

            using (SqlConnection conn = new SqlConnection(Connnection))
166

            {
167

                SqlCommand com = new SqlCommand(ReadSql, conn);
168

                conn.Open();
169

                object CountResult = com.ExecuteScalar();
170

                conn.Close();
171

                Console.WriteLine("数据记录为:{0}", CountResult);
172

            }
173

        }
174


175

        /// <summary>
176

        /// 根据Guid查询;
177

        /// </summary>
178

        private void Guid_SelectById()
179

        {
180

            string ReadSql = "select * from Table_Guid where Guid='C1763624-036D-4DB9-A1E4-7E16318C30DE'";
181

            using (SqlConnection conn = new SqlConnection(Connnection))
182

            {
183

                SqlCommand com = new SqlCommand(ReadSql, conn);
184

                conn.Open();
185

                object IdResult = com.ExecuteScalar();
186

                Console.WriteLine("Guid为{0}", IdResult);
187

                conn.Close();
188

            }
189

        }
190

    }
191


192

}
193


 
  3.数据库的插入测试
  测试1
  数据库量为:100条
  运行结果
 


  测试2
  数据库量为:10000条
运行结果
 


测试3
  数据库量为:100000条
运行结果 
 


  测试4
  数据库量为:500000条
  运行结果



   4.将数据读到DataSet中
  测试1
  读取数据量:100
  运行结果



  测试2
  读取数据量:10000
  运行结果
 


  测试3
  读取数据量:100000
  运行结果



   测试4
  读取数据量:500000
  运行结果
 


  4.记录总数测试
  测试结果



  5.指定条件查询测试
查询数据库中第300000条记录,数量记录量为610300.



4.总结:
  使用Guid作主键速度并不是很慢,它反而要比使用自动增长型的增量速度还要快.
5.参考:
  http://www.cnblogs.com
  http://www.cnblogs.com/leadzen/archive/2008/05/10/1191010.html

原文链接:http://blog.chinaunix.net/uid-20804770-id-1838083.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: