See artikkel on masintõlke peegelartikkel, palun klõpsake siia, et hüpata algse artikli juurde.

Vaade: 13193|Vastuse: 0

[Nõuanded] Võrdle Guid-välja primaarvõtme jõudlust, kasutades teegi iseinkrementaalset välja

[Kopeeri link]
Postitatud 26.10.2015 09:37:04 | | | |
1. Ülevaade:

Meie andmebaasi disainis on põhivõti hädavajalik ning selle disain mõjutab suurt mõju kogu andmebaasi disainile. Võrdlen automaatsete inkrementaalväljade ja Guid-väljade jõudlust, tere tulemast arutlema.

2. Sissejuhatus:

1. Isejärkuvad väljad

      Isejärkuvad väljad suurenevad iga kord järjestikku, tagades, et tabeli primaarvõtmed ei korduks. Kui isekasvava välja tüübi maksimaalset väärtust ei ületata ega suurendata nullist, on see peaaegu võimatu. On väga lihtne kasutada iseinkrementaalseid välju primaarvõtmetena, tavaliselt deklareeritakse lihtsalt isekasvavad atribuudid tabeli ehitamisel.

      Isejärkuvad väärtused on kõik globaalsed andmeväärtused, mida tuleb süsteemis hoida, ning väärtust suurendatakse iga kord, kui andmed sisestatakse. Samaaegses keskkonnas, kus ekvivalent genereerib unikaalse identiteedi, tuleb iga inkrementaalne väärtus lukustada ja avada selle globaalse väärtusega, et tagada inkrementi unikaalsus. See võib olla samaaegne pudelikael, mis toob kaasa mõningaid jõudlusprobleeme.

Andmete migreerimisel või importimisel võivad iseinkrementaalsed väljad dubleerida, mis on kahtlemata õudusunenägu (olen sellest juba kannatanud).

      Kui tahad luua hajutatud andmebaasi, on see isejärkumise väli probleem. See on tingitud sellest, et hajutatud andmebaasis võib sama nimega tabelid erinevatest andmebaasidest olla vajalik sünkroonselt replitseerimisel. Andmebaasitabeli eneseinkrementaalne väärtus dubleerub tõenäoliselt sama tabeli eneseinkrementaalse väärtusega teises andmebaasis.

2. unikaalidentifikaatori (Guid) väli

MS SQL andmebaasides saab tabeli struktuuri luua, määrates välja tüübiks unikaalse identifikaatori, ning selle vaikimisi väärtuse saab genereerida NewID() abil, et genereerida unikaalne Guid (globaalselt unikaalne identifikaator).

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

GUID-i eeliseks on see, et genereeritud ID on suhteliselt unikaalne, olgu see siis andmete eksportimine või samm-sammuline arendus, probleeme ei esine. Kuid ID, mille see genereerib, on suhteliselt pikk ning andmebaasi ruum on samuti hõivatud, seega pole vaja seda arvestada, kuna välise salvestuse hind langeb. Lisaks pole Guid'i lihtne meelde jätta ja selles osas pole see nii hea kui automaatsed inkrementaalväljad, mis pole programmide silumisel eriti mugav.

3. Testid:

1. Testi keskkonda

Operatsioonisüsteem: Windows Server 2003 R2 Enterprise Edition Service Pack 2

Andmebaas: MS SQL 2005

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

Mälu: DDRII. 667 1G

Kõvaketas: WD 80G

2. Andmebaasi skriptid
  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
Kopeeri kood
Testkood
  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
Kopeeri kood
3. Andmebaasi sisestamise test
Test 1
Andmebaasi maht on: 100 üksust
Näita tulemust
Test 2
Andmebaasi maht on: 10 000 üksust
Näita tulemust

Test 3
Andmebaasi maht on: 100 000 üksust
Näita tulemust
Test 4
Andmebaasi maht on: 500 000 üksust
Näita tulemust
4. Loe andmed andmekogumisse
Test 1
Loetud andmete hulk: 100
Näita tulemust
Test 2
Loetud andmemaht: 10 000
Näita tulemust
Test 3
Loetud andmete hulk: 100 000
Näita tulemust
Test 4
Loetud andmete hulk: 500 000
Näita tulemust
4. Salvesta koguarvu test
Testitulemused
5. Määra tingimuspäringutest
300 000. kirje päringute andmebaasis on 610 300.
4. Kokkuvõte:
Guidi kasutamine peamise võtmena ei ole väga aeglane, kuid kiirem kui automaatselt kasvavate sammude kasutamine.





Eelmine:asp.net teisendada binaarne Base64 sisu piltideks ja salvestada neid kohapeal
Järgmine:String[3]: Suuruse omadusel on kehtetu suurus 0.
Disclaimer:
Kõik Code Farmer Networki poolt avaldatud tarkvara, programmeerimismaterjalid või artiklid on mõeldud ainult õppimiseks ja uurimistööks; Ülaltoodud sisu ei tohi kasutada ärilistel ega ebaseaduslikel eesmärkidel, vastasel juhul kannavad kasutajad kõik tagajärjed. Selle saidi info pärineb internetist ning autoriõiguste vaidlused ei ole selle saidiga seotud. Ülaltoodud sisu tuleb oma arvutist täielikult kustutada 24 tunni jooksul pärast allalaadimist. Kui sulle programm meeldib, palun toeta originaaltarkvara, osta registreerimist ja saa paremaid ehtsaid teenuseid. Kui esineb rikkumist, palun võtke meiega ühendust e-posti teel.

Mail To:help@itsvse.com