Tento článok je zrkadlovým článkom o strojovom preklade, kliknite sem pre prechod na pôvodný článok.

Pohľad: 13193|Odpoveď: 0

[Tipy] Porovnajte výkon primárneho kľúča poľa Guid pomocou samoinkrementálneho poľa v knižnici

[Kopírovať odkaz]
Zverejnené 26. 10. 2015 9:37:04 | | | |
1. Prehľad:

V našom návrhu databázy je primárny kľúč databázy nevyhnutný a návrh primárneho kľúča má veľký vplyv na dizajn celej databázy. Porovnám výkon automaticky inkrementálnych polí a Guid polí, vitajte na diskusiu.

2. Úvod:

1. Samoinkrementálne polia

      Samoinkrementálne polia sa postupne zvyšujú zakaždým, čím sa zabezpečuje, že primárne kľúče v tabuľke sa neopakujú. Pokiaľ nie je prekročená a zvyšovaná maximálna hodnota samozvyšujúceho sa typu poľa od nuly, je to takmer nemožné. Je veľmi jednoduché použiť samoinkrementálne polia ako primárne kľúče, zvyčajne len deklarovať samoinkrementujúce atribúty pri tvorbe tabuľky.

      Samoinkrementálne hodnoty sú všetky globálne dátové hodnoty, ktoré je potrebné udržiavať v systéme, a hodnota sa zvyšuje pri každom vložení dát. V súbežnom prostredí, kde ekvivalent generuje jedinečnú identitu, musí byť každá inkrementálna hodnota uzamknutá a odomknutá touto globálnou hodnotou, aby sa zabezpečila jedinečnosť prírastku. Môže to byť súbežné úzke miesto, ktoré prináša určité problémy s výkonom.

Pri migrácii alebo importe dát môžu byť samoinkrementálne polia duplikované, čo je nepochybne nočná mora (už som tým trpel).

      Ak chcete vytvoriť distribuovanú databázu, toto samoinkrementálne pole je problém. Je to preto, že v distribuovanej databáze môžu byť tabuľky s rovnakým názvom z rôznych databáz potrebné replikovať synchronne. Samoinkrementálna hodnota databázovej tabuľky sa pravdepodobne duplikuje so samoinkrementálnou hodnotou tej istej tabuľky v inej databáze.

2. pole uniqueidentifier (Guid)

V databázach MS SQL je možné štruktúru tabuľky vytvoriť zadaním typu poľa ako uniqueidentifier a jej predvolenú hodnotu možno vygenerovať pomocou NewID() na generovanie jedinečného Guid (Globally Unique Identifier).

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

Výhodou GUID je, že generované ID je relatívne jedinečné, či už ide o export dát alebo krok za krokom vývoj, nebudú žiadne problémy. Avšak ID, ktoré generuje, je relatívne dlhé a databázový priestor je tiež obsadený, takže to nie je potrebné brať do úvahy, keďže cena externého úložiska klesá. Okrem toho Guid nie je ľahké si zapamätať, a v tomto ohľade nie je taký dobrý ako automatické inkrementálne polia, čo nie je veľmi pohodlné pri ladení programov.

3. Testovanie:

1. Otestujte prostredie

Operačný systém: Windows Server 2003 R2 Enterprise Edition Service Pack 2

Databáza: MS SQL 2005

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

Pamäť: DDRII. 667 1G

Pevný disk: WD 80G

2. Databázové skripty
  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
Kopírovať kód
Testovací kód
  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
Kopírovať kód
3. Test vkladania do databázy
Test 1
Objem databázy je: 100 položiek
Spusti výsledok
Test 2
Objem databázy je: 10 000 položiek
Spusti výsledok

Test 3
Objem databázy je: 100 000 položiek
Spusti výsledok
Test 4
Objem databázy je: 500 000 položiek
Spusti výsledok
4. Načítať dáta do DataSetu
Test 1
Množstvo prečítaných dát: 100
Spusti výsledok
Test 2
Množstvo prečítaných dát: 10 000
Spusti výsledok
Test 3
Množstvo prečítaných údajov: 100 000
Spusti výsledok
Test 4
Množstvo prečítaných dát: 500 000
Spusti výsledok
4. Zaznamenať celkový počet testov
Výsledky testov
5. Špecifikovať test dotazu na podmienku
300 000. záznam v databáze dotazov je 610 300.
4. Zhrnutie:
Používanie Guid ako hlavného kľúča nie je veľmi pomalé, ale rýchlejšie ako používanie automaticky rastúcich inkrementov.





Predchádzajúci:asp.net konvertovať binárny obsah Base64 na obrázky a ukladať ich lokálne
Budúci:Reťaz[3]: vlastnosť Veľkosť má neplatnú veľkosť 0.
Vyhlásenie:
Všetok softvér, programovacie materiály alebo články publikované spoločnosťou Code Farmer Network slúžia len na vzdelávacie a výskumné účely; Vyššie uvedený obsah nesmie byť použitý na komerčné alebo nezákonné účely, inak nesú všetky následky používateľmi. Informácie na tejto stránke pochádzajú z internetu a spory o autorské práva s touto stránkou nesúvisia. Musíte úplne vymazať vyššie uvedený obsah zo svojho počítača do 24 hodín od stiahnutia. Ak sa vám program páči, podporte originálny softvér, zakúpte si registráciu a získajte lepšie originálne služby. Ak dôjde k akémukoľvek porušeniu, kontaktujte nás prosím e-mailom.

Mail To:help@itsvse.com