diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/AboutSqlServer.Com.Classes.csproj b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/AboutSqlServer.Com.Classes.csproj new file mode 100644 index 0000000..989bd6f --- /dev/null +++ b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/AboutSqlServer.Com.Classes.csproj @@ -0,0 +1,57 @@ + + + + + Debug + AnyCPU + {1D6335A4-DB2A-4A3C-8300-0E98D3114092} + Library + Properties + AboutSqlServer.Com.Classes + AboutSqlServer.Com.Classes + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/BaseThread.cs b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/BaseThread.cs new file mode 100644 index 0000000..e730ed5 --- /dev/null +++ b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/BaseThread.cs @@ -0,0 +1,106 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Common Classes */ +/****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace AboutSqlServer.Com.Classes +{ + public abstract class BaseThread + { + public BaseThread(int sleep) + { + _thread = new Thread(this.Execute); + _sleep = sleep; + _terminated = true; + _iteration = 0; + } + + public void Start() + { + _active = true; + _terminated = false; + OnStart(); + _thread.Start(); + } + + public void Terminate() + { + if (IsActive) + { + _terminated = true; + OnTerminate(); + } + + } + + public int CallsPerSec + { + get + { + // We are not using any thread sync constructs - we do not worry much about possible error. + return (_iteration == 0) ? 0 : (int)(1000 * _iteration / DateTime.Now.Subtract(_startTime).TotalMilliseconds); + } + } + + protected virtual void OnTerminate() { } + protected virtual void OnStart() { } + protected virtual void OnExecute() { _iteration = 0; _startTime = DateTime.Now; } + + private void Execute() + { + using (GetExecuteDisposable()) + { + OnExecute(); + while (!_terminated) + { + _iteration++; + DoIteration(); + if (_sleep == 0) + Thread.Sleep(0); + else + { + int delay = _sleep; + while (!_terminated && (delay > 0)) + { + Thread.Sleep((_sleep < 1000) ? _sleep : 1000); + delay -= 1000; + } + } + } + } + } + + protected virtual IDisposable GetExecuteDisposable() + { + return null; + } + + protected abstract void DoIteration(); + + public bool IsActive { get { return _active; } } + public int Iteration { get { return _iteration; } } + + private Thread _thread; + private int _sleep; + + protected bool _terminated = true; + protected int _iteration; + + private bool _active = false; + + private DateTime _startTime; + } +} diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/ConnectionManager.cs b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/ConnectionManager.cs new file mode 100644 index 0000000..c954b8d --- /dev/null +++ b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/ConnectionManager.cs @@ -0,0 +1,76 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Common Classes */ +/****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Configuration; +using System.Data.SqlClient; + +namespace AboutSqlServer.Com.Classes +{ + public class ConnectionManager + { + public ConnectionManager(string connStrName) + { + if (!String.IsNullOrEmpty(connStrName) && ConfigurationManager.ConnectionStrings[connStrName] != null) + _connStr = ConfigurationManager.ConnectionStrings[connStrName].ConnectionString; + } + + public SqlConnection GetConnection() + { + SqlConnection conn = GetSqlConnection(); + conn.Open(); + return conn; + } + + public bool ValidateConnection(out string connError) + { + using (SqlConnection conn = GetSqlConnection()) + { + try + { + conn.Open(); + conn.Close(); + connError = null; + return true; + } + catch (Exception ex) + { + connError = ex.Message; + return false; + } + } + } + + private SqlConnection GetSqlConnection() + { + if (String.IsNullOrEmpty(_connStr)) + throw new Exception("ConnectionManager::GetSqlConnection() - Connection string has not been specified"); + return new SqlConnection( _connStr); + } + + public string ConnStr + { + get { return _connStr; } + set + { + if (String.IsNullOrEmpty(value)) + throw new Exception("ConnectionManager::SetConnStr() - Connection String is Empty"); + _connStr = value; + } + } + + private string _connStr = null; + } +} diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/ObjStoreUtils.cs b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/ObjStoreUtils.cs new file mode 100644 index 0000000..694f4b8 --- /dev/null +++ b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/ObjStoreUtils.cs @@ -0,0 +1,85 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch & Vladimir Zatuliveter */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Common Classes */ +/****************************************************************************/ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; +using System.Threading.Tasks; + +namespace AboutSqlServer.Com.Classes +{ + public static class ObjStoreUtils + { + /// + /// Serialize object of type T to the byte array + /// + public static byte[] Serialize(T obj) + { + using (var ms = new MemoryStream()) + { + var formatter = new BinaryFormatter(); + formatter.Serialize(ms, obj); + + return ms.ToArray(); + } + } + + /// + /// Deserialize byte array to the object + /// + public static T Deserialize(byte[] data) + { + using (var output = new MemoryStream(data)) + { + var binForm = new BinaryFormatter(); + return (T)binForm.Deserialize(output); + } + } + + /// + /// Split byte array to the multiple chunks + /// + public static List Split(byte[] data, int chunkSize) + { + var result = new List(); + + for (int i = 0; i < data.Length; i += chunkSize) + { + int currentChunkSize = chunkSize; + if (i + chunkSize > data.Length) + currentChunkSize = data.Length - i; + + var buffer = new byte[currentChunkSize]; + Array.Copy(data, i, buffer, 0, currentChunkSize); + + result.Add(buffer); + } + return result; + } + + /// + /// Combine multiple chunks into the byte array + /// + public static byte[] Merge(List arrays) + { + var rv = new byte[arrays.Sum(a => a.Length)]; + int offset = 0; + foreach (byte[] array in arrays) + { + Buffer.BlockCopy(array, 0, rv, offset, array.Length); + offset += array.Length; + } + return rv; + } + } +} diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/Properties/AssemblyInfo.cs b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..922654f --- /dev/null +++ b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AboutSqlServer.Com.Classes")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AboutSqlServer.Com.Classes")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a6852c40-5c61-4754-b628-a7113d06c279")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/StatThread.cs b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/StatThread.cs new file mode 100644 index 0000000..52c1d14 --- /dev/null +++ b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/StatThread.cs @@ -0,0 +1,41 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Common Classes */ +/****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AboutSqlServer.Com.Classes +{ + public abstract class StatThread : BaseThread + { + public StatThread(int sleep, List threads) + : base(sleep) + { + _threads = threads; + } + + public int WorkerThreadsCallsPerSec + { + get + { + int callsPerSec = 0; + foreach (BaseThread thread in _threads) + callsPerSec += thread.CallsPerSec; + return callsPerSec; + } + } + + private List _threads; + } +} diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/bin/Debug/AboutSqlServer.Com.Classes.dll b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/bin/Debug/AboutSqlServer.Com.Classes.dll new file mode 100644 index 0000000..a954af8 Binary files /dev/null and b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/bin/Debug/AboutSqlServer.Com.Classes.dll differ diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/bin/Debug/AboutSqlServer.Com.Classes.pdb b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/bin/Debug/AboutSqlServer.Com.Classes.pdb new file mode 100644 index 0000000..a600120 Binary files /dev/null and b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/bin/Debug/AboutSqlServer.Com.Classes.pdb differ diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.csproj.FileListAbsolute.txt b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..4d94762 --- /dev/null +++ b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.csproj.FileListAbsolute.txt @@ -0,0 +1,5 @@ +C:\.Work\InMemoryOLTP2014\AboutSqlServer.Com.Classes\obj\Debug\AboutSqlServer.Com.Classes.csprojResolveAssemblyReference.cache +C:\.Work\InMemoryOLTP2014\AboutSqlServer.Com.Classes\bin\Debug\AboutSqlServer.Com.Classes.dll +C:\.Work\InMemoryOLTP2014\AboutSqlServer.Com.Classes\bin\Debug\AboutSqlServer.Com.Classes.pdb +C:\.Work\InMemoryOLTP2014\AboutSqlServer.Com.Classes\obj\Debug\AboutSqlServer.Com.Classes.dll +C:\.Work\InMemoryOLTP2014\AboutSqlServer.Com.Classes\obj\Debug\AboutSqlServer.Com.Classes.pdb diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.csprojResolveAssemblyReference.cache b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.csprojResolveAssemblyReference.cache new file mode 100644 index 0000000..d8e404f Binary files /dev/null and b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.csprojResolveAssemblyReference.cache differ diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.dll b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.dll new file mode 100644 index 0000000..a954af8 Binary files /dev/null and b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.dll differ diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.pdb b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.pdb new file mode 100644 index 0000000..a600120 Binary files /dev/null and b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/AboutSqlServer.Com.Classes.pdb differ diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000..bedbcc5 Binary files /dev/null and b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs b/.Net/InMemoryOLTP/AboutSqlServer.Com.Classes/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/InMemoryOLTP/InMemoryOLTP2014.sln b/.Net/InMemoryOLTP/InMemoryOLTP2014.sln new file mode 100644 index 0000000..b270a96 --- /dev/null +++ b/.Net/InMemoryOLTP/InMemoryOLTP2014.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30723.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AboutSqlServer.Com.Classes", "AboutSqlServer.Com.Classes\AboutSqlServer.Com.Classes.csproj", "{1D6335A4-DB2A-4A3C-8300-0E98D3114092}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogRequestsGenerator", "LogRequestsGenerator\LogRequestsGenerator.csproj", "{6622E52A-00B0-48E6-840D-59ABABE2FB5B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SessionStoreDemo", "SessionStoreDemo\SessionStoreDemo.csproj", "{658E533B-B24B-4A22-B19A-B9FA924CC839}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1D6335A4-DB2A-4A3C-8300-0E98D3114092}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D6335A4-DB2A-4A3C-8300-0E98D3114092}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D6335A4-DB2A-4A3C-8300-0E98D3114092}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D6335A4-DB2A-4A3C-8300-0E98D3114092}.Release|Any CPU.Build.0 = Release|Any CPU + {6622E52A-00B0-48E6-840D-59ABABE2FB5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6622E52A-00B0-48E6-840D-59ABABE2FB5B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6622E52A-00B0-48E6-840D-59ABABE2FB5B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6622E52A-00B0-48E6-840D-59ABABE2FB5B}.Release|Any CPU.Build.0 = Release|Any CPU + {658E533B-B24B-4A22-B19A-B9FA924CC839}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {658E533B-B24B-4A22-B19A-B9FA924CC839}.Debug|Any CPU.Build.0 = Debug|Any CPU + {658E533B-B24B-4A22-B19A-B9FA924CC839}.Release|Any CPU.ActiveCfg = Release|Any CPU + {658E533B-B24B-4A22-B19A-B9FA924CC839}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/App.config b/.Net/InMemoryOLTP/LogRequestsGenerator/App.config new file mode 100644 index 0000000..da6c477 --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/App.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/FrmMain.Designer.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/FrmMain.Designer.cs new file mode 100644 index 0000000..fade0b0 --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/FrmMain.Designer.cs @@ -0,0 +1,244 @@ +namespace Actsoft.Com.LogRequestsGenerator +{ + partial class frmMain + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnStop = new System.Windows.Forms.Button(); + this.btnStart = new System.Windows.Forms.Button(); + this.tbCallsPerSec = new System.Windows.Forms.TextBox(); + this.Label4 = new System.Windows.Forms.Label(); + this.cbStoredProc = new System.Windows.Forms.ComboBox(); + this.Label3 = new System.Windows.Forms.Label(); + this.tbThreadNum = new System.Windows.Forms.TextBox(); + this.Label2 = new System.Windows.Forms.Label(); + this.tbConnectionString = new System.Windows.Forms.TextBox(); + this.Label1 = new System.Windows.Forms.Label(); + this.btnValidateConnection = new System.Windows.Forms.Button(); + this.label5 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.SuspendLayout(); + // + // btnStop + // + this.btnStop.Enabled = false; + this.btnStop.Location = new System.Drawing.Point(285, 142); + this.btnStop.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.btnStop.Name = "btnStop"; + this.btnStop.Size = new System.Drawing.Size(73, 32); + this.btnStop.TabIndex = 53; + this.btnStop.Text = "Stop"; + this.btnStop.UseVisualStyleBackColor = true; + this.btnStop.Click += new System.EventHandler(this.btnStop_Click); + // + // btnStart + // + this.btnStart.Location = new System.Drawing.Point(185, 142); + this.btnStart.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.btnStart.Name = "btnStart"; + this.btnStart.Size = new System.Drawing.Size(73, 32); + this.btnStart.TabIndex = 52; + this.btnStart.Text = "Start"; + this.btnStart.UseVisualStyleBackColor = true; + this.btnStart.Click += new System.EventHandler(this.btnStart_Click); + // + // tbCallsPerSec + // + this.tbCallsPerSec.BackColor = System.Drawing.SystemColors.ControlLight; + this.tbCallsPerSec.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.tbCallsPerSec.ForeColor = System.Drawing.Color.Red; + this.tbCallsPerSec.Location = new System.Drawing.Point(267, 97); + this.tbCallsPerSec.Name = "tbCallsPerSec"; + this.tbCallsPerSec.ReadOnly = true; + this.tbCallsPerSec.Size = new System.Drawing.Size(113, 26); + this.tbCallsPerSec.TabIndex = 51; + // + // Label4 + // + this.Label4.AutoSize = true; + this.Label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label4.Location = new System.Drawing.Point(162, 104); + this.Label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.Label4.Name = "Label4"; + this.Label4.Size = new System.Drawing.Size(108, 13); + this.Label4.TabIndex = 50; + this.Label4.Text = "Calls Per Second:"; + // + // cbStoredProc + // + this.cbStoredProc.AllowDrop = true; + this.cbStoredProc.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbStoredProc.FormattingEnabled = true; + this.cbStoredProc.Items.AddRange(new object[] { + "dbo.InsertRequestInfo_Disk", + "dbo.InsertRequestInfo_Memory", + "dbo.InsertRequestInfo_NativelyCompiled"}); + this.cbStoredProc.Location = new System.Drawing.Point(235, 33); + this.cbStoredProc.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.cbStoredProc.Name = "cbStoredProc"; + this.cbStoredProc.Size = new System.Drawing.Size(305, 21); + this.cbStoredProc.TabIndex = 49; + // + // Label3 + // + this.Label3.AutoSize = true; + this.Label3.Location = new System.Drawing.Point(165, 37); + this.Label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.Label3.Name = "Label3"; + this.Label3.Size = new System.Drawing.Size(66, 13); + this.Label3.TabIndex = 48; + this.Label3.Text = "Stored Proc:"; + // + // tbThreadNum + // + this.tbThreadNum.Location = new System.Drawing.Point(107, 33); + this.tbThreadNum.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.tbThreadNum.Name = "tbThreadNum"; + this.tbThreadNum.Size = new System.Drawing.Size(45, 20); + this.tbThreadNum.TabIndex = 47; + this.tbThreadNum.Text = "30"; + // + // Label2 + // + this.Label2.AutoSize = true; + this.Label2.Location = new System.Drawing.Point(33, 36); + this.Label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.Label2.Name = "Label2"; + this.Label2.Size = new System.Drawing.Size(71, 13); + this.Label2.TabIndex = 46; + this.Label2.Text = "# of Threads:"; + // + // tbConnectionString + // + this.tbConnectionString.Location = new System.Drawing.Point(107, 8); + this.tbConnectionString.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.tbConnectionString.Name = "tbConnectionString"; + this.tbConnectionString.Size = new System.Drawing.Size(411, 20); + this.tbConnectionString.TabIndex = 45; + // + // Label1 + // + this.Label1.AutoSize = true; + this.Label1.Location = new System.Drawing.Point(10, 10); + this.Label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.Label1.Name = "Label1"; + this.Label1.Size = new System.Drawing.Size(94, 13); + this.Label1.TabIndex = 44; + this.Label1.Text = "Connection String:"; + // + // btnValidateConnection + // + this.btnValidateConnection.Location = new System.Drawing.Point(522, 11); + this.btnValidateConnection.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.btnValidateConnection.Name = "btnValidateConnection"; + this.btnValidateConnection.Size = new System.Drawing.Size(16, 15); + this.btnValidateConnection.TabIndex = 54; + this.btnValidateConnection.Text = "."; + this.btnValidateConnection.UseVisualStyleBackColor = true; + this.btnValidateConnection.Click += new System.EventHandler(this.btnValidateConnection_Click); + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label5.Location = new System.Drawing.Point(87, 205); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(369, 15); + this.label5.TabIndex = 55; + this.label5.Text = "Expert SQL Server In-Memory OLTP Companion Material"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label6.Location = new System.Drawing.Point(198, 227); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(147, 13); + this.label6.TabIndex = 56; + this.label6.Text = "Written by Dmitri Korotkevitch"; + // + // linkLabel1 + // + this.linkLabel1.AutoSize = true; + this.linkLabel1.Location = new System.Drawing.Point(206, 249); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(130, 13); + this.linkLabel1.TabIndex = 57; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "http://aboutsqlserver.com"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // frmMain + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(543, 271); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.label6); + this.Controls.Add(this.label5); + this.Controls.Add(this.btnValidateConnection); + this.Controls.Add(this.btnStop); + this.Controls.Add(this.btnStart); + this.Controls.Add(this.tbCallsPerSec); + this.Controls.Add(this.Label4); + this.Controls.Add(this.cbStoredProc); + this.Controls.Add(this.Label3); + this.Controls.Add(this.tbThreadNum); + this.Controls.Add(this.Label2); + this.Controls.Add(this.tbConnectionString); + this.Controls.Add(this.Label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.MaximizeBox = false; + this.Name = "frmMain"; + this.Text = "Log Requests Generation Utility"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmMain_FormClosing); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + internal System.Windows.Forms.Button btnStop; + internal System.Windows.Forms.Button btnStart; + private System.Windows.Forms.TextBox tbCallsPerSec; + internal System.Windows.Forms.Label Label4; + internal System.Windows.Forms.ComboBox cbStoredProc; + internal System.Windows.Forms.Label Label3; + internal System.Windows.Forms.TextBox tbThreadNum; + internal System.Windows.Forms.Label Label2; + internal System.Windows.Forms.TextBox tbConnectionString; + internal System.Windows.Forms.Label Label1; + private System.Windows.Forms.Button btnValidateConnection; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.LinkLabel linkLabel1; + } +} + diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/FrmMain.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/FrmMain.cs new file mode 100644 index 0000000..db95aa5 --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/FrmMain.cs @@ -0,0 +1,153 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 2 - Log Requests Generation Utility */ +/****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Data.SqlClient; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using AboutSqlServer.Com.Classes; +using System.Diagnostics; + +namespace Actsoft.Com.LogRequestsGenerator +{ + public partial class frmMain : Form + { + public frmMain() + { + InitializeComponent(); + _connManager = new ConnectionManager("LogRequestsDB"); + tbConnectionString.Text = String.IsNullOrEmpty(_connManager.ConnStr) ? "Server=.;Database=.;Trusted_Connection=True;" : _connManager.ConnStr; + UpdateExecStats = new UpdateExecStatsDelegate(this.UpdateExecStatsMethod); + } + + public void UpdateExecStatsMethod(int callsPerSec) + { + tbCallsPerSec.Text = callsPerSec.ToString(); + } + + + private void btnStart_Click(object sender, EventArgs e) + { + if (_statThread != null) + MessageBox.Show("Log Requests generation is already running", "Log Requests Generation Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); + else + { + Start(); + } + } + + private void Start() + { + int threadCount; + string errMsg; + if (!Int32.TryParse(tbThreadNum.Text, out threadCount)) + { + MessageBox.Show("Invalid # of Threads", "Log Requests Generation Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (String.IsNullOrEmpty(cbStoredProc.Text)) + { + MessageBox.Show("Please select stored procedure", "Log Requests Generation Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (String.IsNullOrEmpty(tbConnectionString.Text)) + { + MessageBox.Show("Please specify connection string", "Log Requests Generation Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _connManager.ConnStr = tbConnectionString.Text; + if (!_connManager.ValidateConnection(out errMsg)) + { + MessageBox.Show( + String.Format("Cannot validate database connection. Error: {0}", errMsg), + "Log Requests Generation Utility", MessageBoxButtons.OK, MessageBoxIcon.Error + ); + return; + } + + _threads = new List(threadCount); + for (int i = 0; i < threadCount; i++) + _threads.Add(new WorkerThread(_connManager, cbStoredProc.Text)); + foreach (WorkerThread thread in _threads) + thread.Start(); + _statThread = new LogRequestsStatThread(5000, _threads, this); + _statThread.Start(); + btnStart.Enabled = false; + btnStop.Enabled = true; + } + + private void btnStop_Click(object sender, EventArgs e) + { + if (_statThread == null) + MessageBox.Show("Log Requests generation is not running", "Log Requests Generation Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); + else + { + Stop(); + MessageBox.Show("Stopped!", "Log Requests Generation Utility", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + private void Stop() + { + _statThread.Terminate(); + foreach (WorkerThread thread in _threads) + thread.Terminate(); + System.Threading.Thread.Sleep(3000); + _statThread = null; + _threads = null; + btnStart.Enabled = true; + btnStop.Enabled = false; + } + + private void frmMain_FormClosing(object sender, FormClosingEventArgs e) + { + if (_statThread != null) + { + Stop(); + System.Threading.Thread.Sleep(1500); + } + } + + private void btnValidateConnection_Click(object sender, EventArgs e) + { + if (String.IsNullOrEmpty(tbConnectionString.Text)) + { + MessageBox.Show("Please specify connection string", "Log Requests Generation Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + string errMsg; + _connManager.ConnStr = tbConnectionString.Text; + if (!_connManager.ValidateConnection(out errMsg)) + MessageBox.Show(String.Format("Cannot validate database connection. Error: {0}", errMsg), "Log Requests Generation Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); + else + MessageBox.Show("OK!", "Log Requests Generation Utility", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + ProcessStartInfo sInfo = new ProcessStartInfo("http://aboutsqlserver.com"); + Process.Start(sInfo); + } + + public delegate void UpdateExecStatsDelegate(int callsPerSec); + public UpdateExecStatsDelegate UpdateExecStats; + private List _threads; + private LogRequestsStatThread _statThread; + private ConnectionManager _connManager; + + } +} diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/FrmMain.resx b/.Net/InMemoryOLTP/LogRequestsGenerator/FrmMain.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/FrmMain.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/LogRequestsGenerator.csproj b/.Net/InMemoryOLTP/LogRequestsGenerator/LogRequestsGenerator.csproj new file mode 100644 index 0000000..7f4984e --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/LogRequestsGenerator.csproj @@ -0,0 +1,98 @@ + + + + + Debug + AnyCPU + {6622E52A-00B0-48E6-840D-59ABABE2FB5B} + WinExe + Properties + AboutSqlServer.Com.LogRequestsGenerator + LogRequestsGenerator + v4.5 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + Form + + + FrmMain.cs + + + + + + + FrmMain.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {1d6335a4-db2a-4a3c-8300-0e98d3114092} + AboutSqlServer.Com.Classes + + + + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/LogRequestsStatThread.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/LogRequestsStatThread.cs new file mode 100644 index 0000000..66b0eaf --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/LogRequestsStatThread.cs @@ -0,0 +1,39 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 2 - Log Requests Generation Utility */ +/****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AboutSqlServer.Com.Classes; + +namespace Actsoft.Com.LogRequestsGenerator +{ + public class LogRequestsStatThread : StatThread + { + public LogRequestsStatThread(int sleep, List threads, frmMain frmMain) + : base(sleep, threads) + { + _frmMain = frmMain; + } + + protected override void DoIteration() + { + if (!_terminated) + { + _frmMain.Invoke(_frmMain.UpdateExecStats, new object[] { WorkerThreadsCallsPerSec }); + } + } + + private frmMain _frmMain; + } +} diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/Program.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/Program.cs new file mode 100644 index 0000000..ce3086a --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/Program.cs @@ -0,0 +1,33 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 2 - Log Requests Generation Utility */ +/****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Actsoft.Com.LogRequestsGenerator +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new frmMain()); + } + } +} diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/AssemblyInfo.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4fd033b --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("LogRequestsGenerator")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("LogRequestsGenerator")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d3f05e0f-adb5-4928-8309-11f29a50be7b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Resources.Designer.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Resources.Designer.cs new file mode 100644 index 0000000..3674a70 --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AboutSqlServer.Com.LogRequestsGenerator.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AboutSqlServer.Com.LogRequestsGenerator.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Resources.resx b/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Settings.Designer.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Settings.Designer.cs new file mode 100644 index 0000000..57cd996 --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AboutSqlServer.Com.LogRequestsGenerator.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Settings.settings b/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/WorkerThread.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/WorkerThread.cs new file mode 100644 index 0000000..7fe8028 --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/WorkerThread.cs @@ -0,0 +1,100 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 2 - Log Requests Generation Utility */ +/****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Threading; +using System.Data.SqlClient; +using System.Data; +using AboutSqlServer.Com.Classes; + +namespace Actsoft.Com.LogRequestsGenerator +{ + public class WorkerThread : BaseThread + { + public WorkerThread(ConnectionManager connManager, string spName) : base(0) + { + this._connManager = connManager; + this._spName = spName; + } + + protected override IDisposable GetExecuteDisposable() + { + _conn = _connManager.GetConnection(); + return _conn; + } + + protected override void OnExecute() + { + base.OnExecute(); + _cmd = CreateCommand(); + _cmd.Connection = _conn; + } + + private SqlCommand CreateCommand() + { + SqlCommand cmd = new SqlCommand(_spName); + cmd.CommandType = System.Data.CommandType.StoredProcedure; + cmd.Parameters.Add("@URL",SqlDbType.VarChar,255).Value = "http://mywebsite.com/OneOfAppURL"; + cmd.Parameters.Add("@RequestType",SqlDbType.TinyInt).Value = 1; + cmd.Parameters.Add("@ClientIP",SqlDbType.VarChar,15); + cmd.Parameters.Add("@BytesReceived",SqlDbType.Int); + cmd.Parameters.Add("@Authorization", SqlDbType.VarChar, 256).Value = "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="; + cmd.Parameters.Add("@UserAgent",SqlDbType.VarChar,256).Value = "Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0"; + cmd.Parameters.Add("@Host",SqlDbType.VarChar,256).Value = "www.mywebsite.com"; + cmd.Parameters.Add("@Connection",SqlDbType.VarChar,256).Value = "Upgrade"; + cmd.Parameters.Add("@Referer", SqlDbType.VarChar, 256).Value = "http://mywebsite.com/AnotherURL"; + cmd.Parameters.Add("@Param1",SqlDbType.VarChar,64).Value = "AccountID"; + cmd.Parameters.Add("@Param1Value",SqlDbType.NVarChar,256).Value = "123456"; + cmd.Parameters.Add("@Param2",SqlDbType.VarChar,64).Value = "UserID"; + cmd.Parameters.Add("@Param2Value",SqlDbType.NVarChar,256); + cmd.Parameters.Add("@Param3",SqlDbType.VarChar,64).Value = "StartTime"; + cmd.Parameters.Add("@Param3Value",SqlDbType.NVarChar,256); + cmd.Parameters.Add("@Param4",SqlDbType.VarChar,64).Value = "StopTime";; + cmd.Parameters.Add("@Param4Value",SqlDbType.NVarChar,256); + cmd.Parameters.Add("@Param5",SqlDbType.VarChar,64).Value = "Sort";; + cmd.Parameters.Add("@Param5Value",SqlDbType.NVarChar,256); + return cmd; + } + + protected sealed override void DoIteration() + { + _cmd.Parameters[2].Value = String.Format("{0}.{1}.{2}.{3}", DateTime.Now.Millisecond % 254 + 1, DateTime.Now.Millisecond % 254, _iteration % 254, _iteration % 999); + _cmd.Parameters[3].Value = 1000 * (_iteration % 4 + 1); + switch (_iteration % 5) + { + case 0: _cmd.Parameters[12].Value = _cmd.Parameters[14].Value = _cmd.Parameters[16].Value = _cmd.Parameters[18].Value = DBNull.Value; break; + case 1: _cmd.Parameters[12].Value = "23456"; + _cmd.Parameters[14].Value = _cmd.Parameters[16].Value = _cmd.Parameters[18].Value = DBNull.Value; break; + case 2: _cmd.Parameters[12].Value = "4567"; + _cmd.Parameters[14].Value = "2015-01-01T10:00:00"; + _cmd.Parameters[16].Value = _cmd.Parameters[18].Value = DBNull.Value; break; + case 3: _cmd.Parameters[12].Value = "4567"; + _cmd.Parameters[14].Value = "2015-01-01T10:00:00"; + _cmd.Parameters[16].Value = "2015-02-01T10:00:00"; + _cmd.Parameters[18].Value = DBNull.Value; break; + case 4: _cmd.Parameters[12].Value = "4567"; + _cmd.Parameters[14].Value = "2015-01-01T10:00:00"; + _cmd.Parameters[16].Value = "2015-02-01T10:00:00"; + _cmd.Parameters[18].Value = 100; break; + } + _cmd.ExecuteNonQuery(); + } + + private ConnectionManager _connManager; + private string _spName; + private SqlConnection _conn; + private SqlCommand _cmd; + } +} diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/AboutSqlServer.Com.Classes.dll b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/AboutSqlServer.Com.Classes.dll new file mode 100644 index 0000000..a954af8 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/AboutSqlServer.Com.Classes.dll differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/AboutSqlServer.Com.Classes.pdb b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/AboutSqlServer.Com.Classes.pdb new file mode 100644 index 0000000..a600120 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/AboutSqlServer.Com.Classes.pdb differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.exe b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.exe new file mode 100644 index 0000000..b3c7351 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.exe differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.exe.config b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.exe.config new file mode 100644 index 0000000..da6c477 --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.exe.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.pdb b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.pdb new file mode 100644 index 0000000..2cfa238 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.pdb differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.vshost.exe b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.vshost.exe new file mode 100644 index 0000000..666c0af Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.vshost.exe differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.vshost.exe.config b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.vshost.exe.config new file mode 100644 index 0000000..d61742a --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/bin/Debug/LogRequestsGenerator.vshost.exe.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/AboutSqlServer.Com.LogRequestsGenerator.Properties.Resources.resources b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/AboutSqlServer.Com.LogRequestsGenerator.Properties.Resources.resources new file mode 100644 index 0000000..6c05a97 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/AboutSqlServer.Com.LogRequestsGenerator.Properties.Resources.resources differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/Actsoft.Com.LogRequestsGenerator.frmMain.resources b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/Actsoft.Com.LogRequestsGenerator.frmMain.resources new file mode 100644 index 0000000..6c05a97 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/Actsoft.Com.LogRequestsGenerator.frmMain.resources differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/DesignTimeResolveAssemblyReferences.cache b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/DesignTimeResolveAssemblyReferences.cache new file mode 100644 index 0000000..54e47b4 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/DesignTimeResolveAssemblyReferences.cache differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000..3e69370 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.Properties.Resources.resources b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.Properties.Resources.resources new file mode 100644 index 0000000..6c05a97 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.Properties.Resources.resources differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.csproj.FileListAbsolute.txt b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..afb6030 --- /dev/null +++ b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.csproj.FileListAbsolute.txt @@ -0,0 +1,29 @@ +C:\.Work\LogRequestsGenerator\LogRequestsGenerator\bin\Debug\LogRequestsGenerator.exe.config +C:\.Work\LogRequestsGenerator\LogRequestsGenerator\bin\Debug\LogRequestsGenerator.exe +C:\.Work\LogRequestsGenerator\LogRequestsGenerator\bin\Debug\LogRequestsGenerator.pdb +C:\.Work\LogRequestsGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.csprojResolveAssemblyReference.cache +C:\.Work\LogRequestsGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.frmMain.resources +C:\.Work\LogRequestsGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.Properties.Resources.resources +C:\.Work\LogRequestsGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.csproj.GenerateResource.Cache +C:\.Work\LogRequestsGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.exe +C:\.Work\LogRequestsGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.pdb +c:\.Work\LogRequestGenerator\LogRequestsGenerator\bin\Debug\LogRequestsGenerator.exe.config +c:\.Work\LogRequestGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.exe +c:\.Work\LogRequestGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.pdb +c:\.Work\LogRequestGenerator\LogRequestsGenerator\bin\Debug\LogRequestsGenerator.exe +c:\.Work\LogRequestGenerator\LogRequestsGenerator\bin\Debug\LogRequestsGenerator.pdb +c:\.Work\LogRequestGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.csprojResolveAssemblyReference.cache +c:\.Work\LogRequestGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.frmMain.resources +c:\.Work\LogRequestGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.Properties.Resources.resources +c:\.Work\LogRequestGenerator\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.csproj.GenerateResource.Cache +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.csprojResolveAssemblyReference.cache +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\obj\Debug\Actsoft.Com.LogRequestsGenerator.frmMain.resources +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\obj\Debug\AboutSqlServer.Com.LogRequestsGenerator.Properties.Resources.resources +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.csproj.GenerateResource.Cache +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.exe +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\obj\Debug\LogRequestsGenerator.pdb +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\bin\Debug\LogRequestsGenerator.exe.config +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\bin\Debug\LogRequestsGenerator.exe +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\bin\Debug\LogRequestsGenerator.pdb +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\bin\Debug\AboutSqlServer.Com.Classes.dll +C:\.Work\InMemoryOLTP2014\LogRequestsGenerator\bin\Debug\AboutSqlServer.Com.Classes.pdb diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.csproj.GenerateResource.Cache b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.csproj.GenerateResource.Cache new file mode 100644 index 0000000..9f9a86e Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.csproj.GenerateResource.Cache differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.csprojResolveAssemblyReference.cache b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.csprojResolveAssemblyReference.cache new file mode 100644 index 0000000..625485a Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.csprojResolveAssemblyReference.cache differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.exe b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.exe new file mode 100644 index 0000000..b3c7351 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.exe differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.frmMain.resources b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.frmMain.resources new file mode 100644 index 0000000..6c05a97 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.frmMain.resources differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.pdb b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.pdb new file mode 100644 index 0000000..2cfa238 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/LogRequestsGenerator.pdb differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll new file mode 100644 index 0000000..da60d97 Binary files /dev/null and b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll differ diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs b/.Net/InMemoryOLTP/LogRequestsGenerator/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/App.config b/.Net/InMemoryOLTP/SessionStoreDemo/App.config new file mode 100644 index 0000000..b1f467f --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/App.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/FrmMain.Designer.cs b/.Net/InMemoryOLTP/SessionStoreDemo/FrmMain.Designer.cs new file mode 100644 index 0000000..627405f --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/FrmMain.Designer.cs @@ -0,0 +1,294 @@ +namespace Actsoft.Com.SessionStoreDemo +{ + partial class frmMain + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnStop = new System.Windows.Forms.Button(); + this.btnStart = new System.Windows.Forms.Button(); + this.tbCallsPerSec = new System.Windows.Forms.TextBox(); + this.Label4 = new System.Windows.Forms.Label(); + this.Label3 = new System.Windows.Forms.Label(); + this.tbThreadNum = new System.Windows.Forms.TextBox(); + this.Label2 = new System.Windows.Forms.Label(); + this.tbConnectionString = new System.Windows.Forms.TextBox(); + this.Label1 = new System.Windows.Forms.Label(); + this.btnValidateConnection = new System.Windows.Forms.Button(); + this.label5 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.cbUseInMemoryOLTP = new System.Windows.Forms.CheckBox(); + this.tbSessionSize = new System.Windows.Forms.TextBox(); + this.cbUseTVP = new System.Windows.Forms.CheckBox(); + this.tbNumIterations = new System.Windows.Forms.TextBox(); + this.label7 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // btnStop + // + this.btnStop.Enabled = false; + this.btnStop.Location = new System.Drawing.Point(285, 177); + this.btnStop.Margin = new System.Windows.Forms.Padding(2); + this.btnStop.Name = "btnStop"; + this.btnStop.Size = new System.Drawing.Size(73, 32); + this.btnStop.TabIndex = 53; + this.btnStop.Text = "Stop"; + this.btnStop.UseVisualStyleBackColor = true; + this.btnStop.Click += new System.EventHandler(this.btnStop_Click); + // + // btnStart + // + this.btnStart.Location = new System.Drawing.Point(185, 177); + this.btnStart.Margin = new System.Windows.Forms.Padding(2); + this.btnStart.Name = "btnStart"; + this.btnStart.Size = new System.Drawing.Size(73, 32); + this.btnStart.TabIndex = 52; + this.btnStart.Text = "Start"; + this.btnStart.UseVisualStyleBackColor = true; + this.btnStart.Click += new System.EventHandler(this.btnStart_Click); + // + // tbCallsPerSec + // + this.tbCallsPerSec.BackColor = System.Drawing.SystemColors.ControlLight; + this.tbCallsPerSec.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.tbCallsPerSec.ForeColor = System.Drawing.Color.Red; + this.tbCallsPerSec.Location = new System.Drawing.Point(267, 132); + this.tbCallsPerSec.Name = "tbCallsPerSec"; + this.tbCallsPerSec.ReadOnly = true; + this.tbCallsPerSec.Size = new System.Drawing.Size(113, 26); + this.tbCallsPerSec.TabIndex = 51; + // + // Label4 + // + this.Label4.AutoSize = true; + this.Label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label4.Location = new System.Drawing.Point(162, 139); + this.Label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.Label4.Name = "Label4"; + this.Label4.Size = new System.Drawing.Size(108, 13); + this.Label4.TabIndex = 50; + this.Label4.Text = "Calls Per Second:"; + // + // Label3 + // + this.Label3.AutoSize = true; + this.Label3.Location = new System.Drawing.Point(41, 59); + this.Label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.Label3.Name = "Label3"; + this.Label3.Size = new System.Drawing.Size(105, 13); + this.Label3.TabIndex = 48; + this.Label3.Text = "Session Size (Bytes):"; + // + // tbThreadNum + // + this.tbThreadNum.Location = new System.Drawing.Point(150, 32); + this.tbThreadNum.Margin = new System.Windows.Forms.Padding(2); + this.tbThreadNum.Name = "tbThreadNum"; + this.tbThreadNum.Size = new System.Drawing.Size(67, 20); + this.tbThreadNum.TabIndex = 47; + this.tbThreadNum.Text = "30"; + // + // Label2 + // + this.Label2.AutoSize = true; + this.Label2.Location = new System.Drawing.Point(75, 35); + this.Label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.Label2.Name = "Label2"; + this.Label2.Size = new System.Drawing.Size(71, 13); + this.Label2.TabIndex = 46; + this.Label2.Text = "# of Threads:"; + // + // tbConnectionString + // + this.tbConnectionString.Location = new System.Drawing.Point(150, 8); + this.tbConnectionString.Margin = new System.Windows.Forms.Padding(2); + this.tbConnectionString.Name = "tbConnectionString"; + this.tbConnectionString.Size = new System.Drawing.Size(368, 20); + this.tbConnectionString.TabIndex = 45; + // + // Label1 + // + this.Label1.AutoSize = true; + this.Label1.Location = new System.Drawing.Point(52, 11); + this.Label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.Label1.Name = "Label1"; + this.Label1.Size = new System.Drawing.Size(94, 13); + this.Label1.TabIndex = 44; + this.Label1.Text = "Connection String:"; + // + // btnValidateConnection + // + this.btnValidateConnection.Location = new System.Drawing.Point(522, 11); + this.btnValidateConnection.Margin = new System.Windows.Forms.Padding(2); + this.btnValidateConnection.Name = "btnValidateConnection"; + this.btnValidateConnection.Size = new System.Drawing.Size(16, 15); + this.btnValidateConnection.TabIndex = 54; + this.btnValidateConnection.Text = "."; + this.btnValidateConnection.UseVisualStyleBackColor = true; + this.btnValidateConnection.Click += new System.EventHandler(this.btnValidateConnection_Click); + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label5.Location = new System.Drawing.Point(87, 240); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(369, 15); + this.label5.TabIndex = 55; + this.label5.Text = "Expert SQL Server In-Memory OLTP Companion Material"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label6.Location = new System.Drawing.Point(198, 262); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(147, 13); + this.label6.TabIndex = 56; + this.label6.Text = "Written by Dmitri Korotkevitch"; + // + // linkLabel1 + // + this.linkLabel1.AutoSize = true; + this.linkLabel1.Location = new System.Drawing.Point(206, 284); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(130, 13); + this.linkLabel1.TabIndex = 57; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "http://aboutsqlserver.com"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // cbUseInMemoryOLTP + // + this.cbUseInMemoryOLTP.AutoSize = true; + this.cbUseInMemoryOLTP.Checked = true; + this.cbUseInMemoryOLTP.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbUseInMemoryOLTP.Location = new System.Drawing.Point(235, 32); + this.cbUseInMemoryOLTP.Name = "cbUseInMemoryOLTP"; + this.cbUseInMemoryOLTP.Size = new System.Drawing.Size(128, 17); + this.cbUseInMemoryOLTP.TabIndex = 58; + this.cbUseInMemoryOLTP.Text = "Use In-Memory OLTP"; + this.cbUseInMemoryOLTP.UseVisualStyleBackColor = true; + // + // tbSessionSize + // + this.tbSessionSize.Location = new System.Drawing.Point(150, 56); + this.tbSessionSize.Margin = new System.Windows.Forms.Padding(2); + this.tbSessionSize.Name = "tbSessionSize"; + this.tbSessionSize.Size = new System.Drawing.Size(67, 20); + this.tbSessionSize.TabIndex = 59; + this.tbSessionSize.Text = "5000"; + this.tbSessionSize.TextChanged += new System.EventHandler(this.tbSessionSize_TextChanged); + // + // cbUseTVP + // + this.cbUseTVP.AutoSize = true; + this.cbUseTVP.Checked = true; + this.cbUseTVP.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbUseTVP.Location = new System.Drawing.Point(235, 58); + this.cbUseTVP.Name = "cbUseTVP"; + this.cbUseTVP.Size = new System.Drawing.Size(69, 17); + this.cbUseTVP.TabIndex = 60; + this.cbUseTVP.Text = "Use TVP"; + this.cbUseTVP.UseVisualStyleBackColor = true; + // + // tbNumIterations + // + this.tbNumIterations.Location = new System.Drawing.Point(150, 79); + this.tbNumIterations.Margin = new System.Windows.Forms.Padding(2); + this.tbNumIterations.Name = "tbNumIterations"; + this.tbNumIterations.Size = new System.Drawing.Size(67, 20); + this.tbNumIterations.TabIndex = 62; + this.tbNumIterations.Text = "5"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(38, 82); + this.label7.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(108, 13); + this.label7.TabIndex = 61; + this.label7.Text = "Iterations per Session"; + // + // frmMain + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(543, 308); + this.Controls.Add(this.tbNumIterations); + this.Controls.Add(this.label7); + this.Controls.Add(this.cbUseTVP); + this.Controls.Add(this.tbSessionSize); + this.Controls.Add(this.cbUseInMemoryOLTP); + this.Controls.Add(this.linkLabel1); + this.Controls.Add(this.label6); + this.Controls.Add(this.label5); + this.Controls.Add(this.btnValidateConnection); + this.Controls.Add(this.btnStop); + this.Controls.Add(this.btnStart); + this.Controls.Add(this.tbCallsPerSec); + this.Controls.Add(this.Label4); + this.Controls.Add(this.Label3); + this.Controls.Add(this.tbThreadNum); + this.Controls.Add(this.Label2); + this.Controls.Add(this.tbConnectionString); + this.Controls.Add(this.Label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Margin = new System.Windows.Forms.Padding(2); + this.MaximizeBox = false; + this.Name = "frmMain"; + this.Text = "Session-Store Demo"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmMain_FormClosing); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + internal System.Windows.Forms.Button btnStop; + internal System.Windows.Forms.Button btnStart; + private System.Windows.Forms.TextBox tbCallsPerSec; + internal System.Windows.Forms.Label Label4; + internal System.Windows.Forms.Label Label3; + internal System.Windows.Forms.TextBox tbThreadNum; + internal System.Windows.Forms.Label Label2; + internal System.Windows.Forms.TextBox tbConnectionString; + internal System.Windows.Forms.Label Label1; + private System.Windows.Forms.Button btnValidateConnection; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.CheckBox cbUseInMemoryOLTP; + internal System.Windows.Forms.TextBox tbSessionSize; + private System.Windows.Forms.CheckBox cbUseTVP; + internal System.Windows.Forms.TextBox tbNumIterations; + internal System.Windows.Forms.Label label7; + } +} + diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/FrmMain.cs b/.Net/InMemoryOLTP/SessionStoreDemo/FrmMain.cs new file mode 100644 index 0000000..69ec534 --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/FrmMain.cs @@ -0,0 +1,167 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch & Vladimir Zatuliveter */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11 - Session Store Demo */ +/****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Data.SqlClient; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using AboutSqlServer.Com.Classes; +using System.Diagnostics; + +namespace Actsoft.Com.SessionStoreDemo +{ + public partial class frmMain : Form + { + public frmMain() + { + InitializeComponent(); + _connManager = new ConnectionManager("SessionStoreDemo"); + tbConnectionString.Text = String.IsNullOrEmpty(_connManager.ConnStr) ? "Server=.;Database=.;Trusted_Connection=True;" : _connManager.ConnStr; + UpdateExecStats = new UpdateExecStatsDelegate(this.UpdateExecStatsMethod); + } + + public void UpdateExecStatsMethod(int callsPerSec) + { + tbCallsPerSec.Text = callsPerSec.ToString(); + } + + + private void btnStart_Click(object sender, EventArgs e) + { + if (_statThread != null) + MessageBox.Show("Log Requests generation is already running", "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Error); + else + { + Start(); + } + } + + private void Start() + { + int threadCount, sessionSize, iterationsPerSession; + string errMsg; + if (!Int32.TryParse(tbThreadNum.Text, out threadCount)) + { + MessageBox.Show("Invalid # of Threads", "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (!Int32.TryParse(tbSessionSize.Text, out sessionSize)) + { + MessageBox.Show("Invalid Session Size", "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (!Int32.TryParse(tbNumIterations.Text, out iterationsPerSession)) + { + MessageBox.Show("Invalid # of Iterations per Session", "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (String.IsNullOrEmpty(tbConnectionString.Text)) + { + MessageBox.Show("Please specify connection string", "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + _connManager.ConnStr = tbConnectionString.Text; + if (!_connManager.ValidateConnection(out errMsg)) + { + MessageBox.Show( + String.Format("Cannot validate database connection. Error: {0}", errMsg), + "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Error + ); + return; + } + /* 7,800-byte threshold helps to address binary serialization overhead. That overhead depends on the types of the object properties. In real application + * it is better to analyze the size of serialized object if you want to use different SPs for 1 and multiple data chunks */ + if (sessionSize > 7800 && cbUseTVP.Checked) + MessageBox.Show("Session objects require TVP due to their size", "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Information); + _threads = new List(threadCount); + for (int i = 0; i < threadCount; i++) + _threads.Add(new WorkerThread(_connManager,cbUseInMemoryOLTP.Checked,cbUseTVP.Checked,sessionSize,iterationsPerSession)); + foreach (WorkerThread thread in _threads) + thread.Start(); + _statThread = new SessionStoreStatThread(5000, _threads, this); + _statThread.Start(); + btnStart.Enabled = false; + btnStop.Enabled = true; + } + + private void btnStop_Click(object sender, EventArgs e) + { + if (_statThread == null) + MessageBox.Show("Utility is not running", "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Error); + else + { + Stop(); + MessageBox.Show("Stopped!", "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + private void Stop() + { + _statThread.Terminate(); + foreach (WorkerThread thread in _threads) + thread.Terminate(); + System.Threading.Thread.Sleep(3000); + _statThread = null; + _threads = null; + btnStart.Enabled = true; + btnStop.Enabled = false; + } + + private void frmMain_FormClosing(object sender, FormClosingEventArgs e) + { + if (_statThread != null) + { + Stop(); + System.Threading.Thread.Sleep(1500); + } + } + + private void btnValidateConnection_Click(object sender, EventArgs e) + { + if (String.IsNullOrEmpty(tbConnectionString.Text)) + { + MessageBox.Show("Please specify connection string", "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + string errMsg; + _connManager.ConnStr = tbConnectionString.Text; + if (!_connManager.ValidateConnection(out errMsg)) + MessageBox.Show(String.Format("Cannot validate database connection. Error: {0}", errMsg), "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Error); + else + MessageBox.Show("OK!", "Session Store Demo", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + ProcessStartInfo sInfo = new ProcessStartInfo("http://aboutsqlserver.com"); + Process.Start(sInfo); + } + + private void tbSessionSize_TextChanged(object sender, EventArgs e) + { + int sessionSize; + cbUseTVP.Visible = Int32.TryParse(tbSessionSize.Text, out sessionSize) && sessionSize <= 7800; + } + + public delegate void UpdateExecStatsDelegate(int callsPerSec); + public UpdateExecStatsDelegate UpdateExecStats; + private List _threads; + private SessionStoreStatThread _statThread; + private ConnectionManager _connManager; + + } +} diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/FrmMain.resx b/.Net/InMemoryOLTP/SessionStoreDemo/FrmMain.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/FrmMain.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/Program.cs b/.Net/InMemoryOLTP/SessionStoreDemo/Program.cs new file mode 100644 index 0000000..1dbb579 --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/Program.cs @@ -0,0 +1,34 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch & Vladimir Zatuliveter */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11 - Session Store Demo */ +/****************************************************************************/ + +using Actsoft.Com.SessionStoreDemo; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace AboutSqlServer.Com.SessionStoreDemo +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new frmMain()); + } + } +} diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/Properties/AssemblyInfo.cs b/.Net/InMemoryOLTP/SessionStoreDemo/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d99a06a --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SessionStoreDemo")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SessionStoreDemo")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("909f1cce-1305-46d2-8152-0ac4803372c4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Resources.Designer.cs b/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Resources.Designer.cs new file mode 100644 index 0000000..af8756c --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AboutSqlServer.Com.SessionStoreDemo.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AboutSqlServer.Com.SessionStoreDemo.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Resources.resx b/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Settings.Designer.cs b/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Settings.Designer.cs new file mode 100644 index 0000000..55fd79e --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AboutSqlServer.Com.SessionStoreDemo.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Settings.settings b/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/SessionStoreDemo.csproj b/.Net/InMemoryOLTP/SessionStoreDemo/SessionStoreDemo.csproj new file mode 100644 index 0000000..f8880db --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/SessionStoreDemo.csproj @@ -0,0 +1,97 @@ + + + + + Debug + AnyCPU + {658E533B-B24B-4A22-B19A-B9FA924CC839} + WinExe + Properties + AboutSqlServer.Com.SessionStoreDemo + SessionStoreDemo + v4.5 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + Form + + + FrmMain.cs + + + + + + + FrmMain.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {1d6335a4-db2a-4a3c-8300-0e98d3114092} + AboutSqlServer.Com.Classes + + + + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/SessionStoreStatThread.cs b/.Net/InMemoryOLTP/SessionStoreDemo/SessionStoreStatThread.cs new file mode 100644 index 0000000..3ebec4b --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/SessionStoreStatThread.cs @@ -0,0 +1,39 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch & Vladimir Zatuliveter */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11 - Session Store Demo */ +/****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using AboutSqlServer.Com.Classes; + +namespace Actsoft.Com.SessionStoreDemo +{ + public class SessionStoreStatThread : StatThread + { + public SessionStoreStatThread(int sleep, List threads, frmMain frmMain) + : base(sleep, threads) + { + _frmMain = frmMain; + } + + protected override void DoIteration() + { + if (!_terminated) + { + _frmMain.Invoke(_frmMain.UpdateExecStats, new object[] { WorkerThreadsCallsPerSec }); + } + } + + private frmMain _frmMain; + } +} diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/WorkerThread.cs b/.Net/InMemoryOLTP/SessionStoreDemo/WorkerThread.cs new file mode 100644 index 0000000..5477d9a --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/WorkerThread.cs @@ -0,0 +1,138 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch & Vladimir Zatuliveter */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11 - Session Store Demo */ +/****************************************************************************/ + +/******************************************************************************/ +/* This is oversimplified example to illustrate the basic concepts. Production * + * implementation should have additional code to resolve concurrency conflicts * + /******************************************************************************/ + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Threading; +using System.Data.SqlClient; +using System.Data; +using AboutSqlServer.Com.Classes; + +namespace Actsoft.Com.SessionStoreDemo +{ + public class WorkerThread : BaseThread + { + [Serializable] + class SessionObject + { + public byte[] data; + public int iteration; + + public SessionObject(int objSize) + { + data = Enumerable.Repeat(0,objSize).ToArray(); + iteration = 0; + } + } + + public WorkerThread(ConnectionManager connManager, bool useInMemOLTP, bool useTVP, int objSize, int iterations) : base(0) + { + this._connManager = connManager; + this._obj = new SessionObject(objSize); + this._useTVP = useTVP || (objSize > 7800); + this._useInMemOLTP = useInMemOLTP; + this._iterations = iterations; + } + + protected override IDisposable GetExecuteDisposable() + { + _conn = _connManager.GetConnection(); + return _conn; + } + + protected override void OnExecute() + { + base.OnExecute(); + CreateCommands(_conn); + } + + private void CreateCommands(SqlConnection conn) + { + _cmdLoad = new SqlCommand("dbo.LoadObjectFromStore" + (_useInMemOLTP ? String.Empty : "_Disk"), conn); + _cmdLoad.CommandType = System.Data.CommandType.StoredProcedure; + _cmdLoad.Parameters.Add("@ObjectKey", SqlDbType.UniqueIdentifier); + + _cmdSave = new SqlCommand("dbo.SaveObjectToStore" + + (_useTVP?String.Empty:"_Row") + + (_useInMemOLTP ? String.Empty : "_Disk"), conn); + _cmdSave.CommandType = System.Data.CommandType.StoredProcedure; + _cmdSave.Parameters.Add("@ObjectKey", SqlDbType.UniqueIdentifier); + _cmdSave.Parameters.Add("@ExpirationTime", SqlDbType.DateTime2).Value = DateTime.UtcNow.AddHours(1); + if (_useTVP) + _cmdSave.Parameters.Add("@ObjData", SqlDbType.Structured).TypeName = "dbo.tvpObjData" + (_useInMemOLTP ? String.Empty : "_Disk"); + else + _cmdSave.Parameters.Add("@ObjData", SqlDbType.VarBinary, 8000); + + } + + protected sealed override void DoIteration() + { + if (_iteration % _iterations == 1) + { // Emulating new session + _objectKey = Guid.NewGuid(); + _cmdLoad.Parameters[0].Value = _cmdSave.Parameters[0].Value = _objectKey; + } + else + { // Loading data from db + // Step 1: Getting serialized chunks + _cmdLoad.Parameters[0].Value = _objectKey; + var chunks = new List(); + using (var reader = _cmdLoad.ExecuteReader()) + { + while (reader.Read()) + chunks.Add((byte[])reader[0]); + } + if (chunks.Count == 0) + throw new Exception("Cannot locate an object with key: " + _objectKey.ToString()); + // Step 2: Deserializing + SessionObject loadedObj = ObjStoreUtils.Deserialize(ObjStoreUtils.Merge(chunks)); + // Validation - for demo purposes + if (loadedObj.iteration != _obj.iteration) + throw new Exception("Validation failed: Iterations do not match"); + } + // Saving object to DB + _obj.iteration = _iteration; + byte[] serializedObj = ObjStoreUtils.Serialize(_obj); + if (_useTVP) + { + DataTable tbl = new DataTable(); + tbl.Columns.Add("ChunkNum", typeof(short)); + tbl.Columns.Add("Data", typeof(byte[])); + var chunks = ObjStoreUtils.Split(serializedObj, 8000); + for (int i = 0; i < chunks.Count; i++) + tbl.Rows.Add(i + 1, chunks[i]); + _cmdSave.Parameters[2].Value = tbl; + } + else + _cmdSave.Parameters[2].Value = serializedObj; + _cmdSave.ExecuteNonQuery(); + } + + private ConnectionManager _connManager; + private SqlConnection _conn; + private SqlCommand _cmdLoad; + private SqlCommand _cmdSave; + private SessionObject _obj; + private int _iterations; + private bool _useTVP; + private bool _useInMemOLTP; + private Guid _objectKey; + } +} diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/AboutSqlServer.Com.Classes.dll b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/AboutSqlServer.Com.Classes.dll new file mode 100644 index 0000000..a954af8 Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/AboutSqlServer.Com.Classes.dll differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/AboutSqlServer.Com.Classes.pdb b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/AboutSqlServer.Com.Classes.pdb new file mode 100644 index 0000000..a600120 Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/AboutSqlServer.Com.Classes.pdb differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.exe b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.exe new file mode 100644 index 0000000..7253ebe Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.exe differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.exe.config b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.exe.config new file mode 100644 index 0000000..b1f467f --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.exe.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.pdb b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.pdb new file mode 100644 index 0000000..404f63f Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.pdb differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.vshost.exe b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.vshost.exe new file mode 100644 index 0000000..666c0af Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.vshost.exe differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.vshost.exe.config b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.vshost.exe.config new file mode 100644 index 0000000..fbf7815 --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/bin/Debug/SessionStoreDemo.vshost.exe.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/AboutSqlServer.Com.SessionStoreDemo.Properties.Resources.resources b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/AboutSqlServer.Com.SessionStoreDemo.Properties.Resources.resources new file mode 100644 index 0000000..6c05a97 Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/AboutSqlServer.Com.SessionStoreDemo.Properties.Resources.resources differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/Actsoft.Com.SessionStoreDemo.frmMain.resources b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/Actsoft.Com.SessionStoreDemo.frmMain.resources new file mode 100644 index 0000000..6c05a97 Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/Actsoft.Com.SessionStoreDemo.frmMain.resources differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000..90043cd Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.csproj.FileListAbsolute.txt b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..282d077 --- /dev/null +++ b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.csproj.FileListAbsolute.txt @@ -0,0 +1,11 @@ +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\obj\Debug\SessionStoreDemo.csprojResolveAssemblyReference.cache +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\obj\Debug\Actsoft.Com.SessionStoreDemo.frmMain.resources +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\obj\Debug\AboutSqlServer.Com.SessionStoreDemo.Properties.Resources.resources +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\obj\Debug\SessionStoreDemo.csproj.GenerateResource.Cache +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\bin\Debug\SessionStoreDemo.exe.config +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\bin\Debug\SessionStoreDemo.exe +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\bin\Debug\SessionStoreDemo.pdb +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\bin\Debug\AboutSqlServer.Com.Classes.dll +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\bin\Debug\AboutSqlServer.Com.Classes.pdb +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\obj\Debug\SessionStoreDemo.exe +C:\.Work\InMemoryOLTP2014\SessionStoreDemo\obj\Debug\SessionStoreDemo.pdb diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.csproj.GenerateResource.Cache b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.csproj.GenerateResource.Cache new file mode 100644 index 0000000..680de4e Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.csproj.GenerateResource.Cache differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.csprojResolveAssemblyReference.cache b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.csprojResolveAssemblyReference.cache new file mode 100644 index 0000000..f94c78d Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.csprojResolveAssemblyReference.cache differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.exe b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.exe new file mode 100644 index 0000000..7253ebe Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.exe differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.pdb b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.pdb new file mode 100644 index 0000000..404f63f Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/SessionStoreDemo.pdb differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll new file mode 100644 index 0000000..946cd67 Binary files /dev/null and b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll differ diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs b/.Net/InMemoryOLTP/SessionStoreDemo/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/SaveRecordSetApp/MainForm.Designer.cs b/.Net/SaveRecordSetApp/MainForm.Designer.cs new file mode 100644 index 0000000..9353bb0 --- /dev/null +++ b/.Net/SaveRecordSetApp/MainForm.Designer.cs @@ -0,0 +1,399 @@ +namespace SaveRecordSetApp +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.lblPacketSize = new System.Windows.Forms.Label(); + this.tbPacketSize = new System.Windows.Forms.TextBox(); + this.btnSeparateInserts = new System.Windows.Forms.Button(); + this.btnTvp = new System.Windows.Forms.Button(); + this.btnElementCentric = new System.Windows.Forms.Button(); + this.btnAttributeCentric = new System.Windows.Forms.Button(); + this.btnOpenXml = new System.Windows.Forms.Button(); + this.btnAttributeCentricTempTable = new System.Windows.Forms.Button(); + this.tbConnString = new System.Windows.Forms.TextBox(); + this.btnBulkCopy = new System.Windows.Forms.Button(); + this.lblSeparateInsertInfo = new System.Windows.Forms.Label(); + this.lblTVPInfo = new System.Windows.Forms.Label(); + this.lblElementCentricXMLInfo = new System.Windows.Forms.Label(); + this.lblAttributeCentricXMLInfo = new System.Windows.Forms.Label(); + this.lblOpenXMLInfo = new System.Windows.Forms.Label(); + this.lblAttributeCentricTempTableInfo = new System.Windows.Forms.Label(); + this.lblSQLBulkCopyInfo = new System.Windows.Forms.Label(); + this.lblURL = new System.Windows.Forms.LinkLabel(); + this.labelBookInfo = new System.Windows.Forms.Label(); + this.lblInfo2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.lblSiResult = new System.Windows.Forms.Label(); + this.lblTVPResult = new System.Windows.Forms.Label(); + this.lblECXMLResult = new System.Windows.Forms.Label(); + this.lblACXMLResult = new System.Windows.Forms.Label(); + this.lblOXMLResult = new System.Windows.Forms.Label(); + this.lblACTTXMLResult = new System.Windows.Forms.Label(); + this.lblBCResult = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // lblPacketSize + // + this.lblPacketSize.AutoSize = true; + this.lblPacketSize.Location = new System.Drawing.Point(13, 79); + this.lblPacketSize.Name = "lblPacketSize"; + this.lblPacketSize.Size = new System.Drawing.Size(67, 13); + this.lblPacketSize.TabIndex = 0; + this.lblPacketSize.Text = "Packet Size:"; + // + // tbPacketSize + // + this.tbPacketSize.Location = new System.Drawing.Point(86, 76); + this.tbPacketSize.Name = "tbPacketSize"; + this.tbPacketSize.Size = new System.Drawing.Size(100, 20); + this.tbPacketSize.TabIndex = 1; + this.tbPacketSize.Text = "5000"; + // + // btnSeparateInserts + // + this.btnSeparateInserts.Location = new System.Drawing.Point(16, 107); + this.btnSeparateInserts.Name = "btnSeparateInserts"; + this.btnSeparateInserts.Size = new System.Drawing.Size(137, 23); + this.btnSeparateInserts.TabIndex = 3; + this.btnSeparateInserts.Text = "Separate inserts"; + this.btnSeparateInserts.UseVisualStyleBackColor = true; + this.btnSeparateInserts.Click += new System.EventHandler(this.btnSeparateInserts_Click); + // + // btnTvp + // + this.btnTvp.Location = new System.Drawing.Point(16, 136); + this.btnTvp.Name = "btnTvp"; + this.btnTvp.Size = new System.Drawing.Size(137, 23); + this.btnTvp.TabIndex = 4; + this.btnTvp.Text = "TVP"; + this.btnTvp.UseVisualStyleBackColor = true; + this.btnTvp.Click += new System.EventHandler(this.btnTvp_Click); + // + // btnElementCentric + // + this.btnElementCentric.Location = new System.Drawing.Point(16, 165); + this.btnElementCentric.Name = "btnElementCentric"; + this.btnElementCentric.Size = new System.Drawing.Size(137, 23); + this.btnElementCentric.TabIndex = 5; + this.btnElementCentric.Text = "Element-Centric XML"; + this.btnElementCentric.UseVisualStyleBackColor = true; + this.btnElementCentric.Click += new System.EventHandler(this.btnElementCentric_Click); + // + // btnAttributeCentric + // + this.btnAttributeCentric.Location = new System.Drawing.Point(16, 194); + this.btnAttributeCentric.Name = "btnAttributeCentric"; + this.btnAttributeCentric.Size = new System.Drawing.Size(137, 23); + this.btnAttributeCentric.TabIndex = 6; + this.btnAttributeCentric.Text = "Attribute-Centric XML"; + this.btnAttributeCentric.UseVisualStyleBackColor = true; + this.btnAttributeCentric.Click += new System.EventHandler(this.btnAttributeCentric_Click); + // + // btnOpenXml + // + this.btnOpenXml.Location = new System.Drawing.Point(16, 224); + this.btnOpenXml.Name = "btnOpenXml"; + this.btnOpenXml.Size = new System.Drawing.Size(137, 23); + this.btnOpenXml.TabIndex = 7; + this.btnOpenXml.Text = "Open XML"; + this.btnOpenXml.UseVisualStyleBackColor = true; + this.btnOpenXml.Click += new System.EventHandler(this.btnOpenXml_Click); + // + // btnAttributeCentricTempTable + // + this.btnAttributeCentricTempTable.Location = new System.Drawing.Point(16, 253); + this.btnAttributeCentricTempTable.Name = "btnAttributeCentricTempTable"; + this.btnAttributeCentricTempTable.Size = new System.Drawing.Size(137, 41); + this.btnAttributeCentricTempTable.TabIndex = 8; + this.btnAttributeCentricTempTable.Text = "Attribute-Centric XML with Temp Table"; + this.btnAttributeCentricTempTable.UseVisualStyleBackColor = true; + this.btnAttributeCentricTempTable.Click += new System.EventHandler(this.btnAttributeCentric_Click); + // + // tbConnString + // + this.tbConnString.Location = new System.Drawing.Point(204, 76); + this.tbConnString.Name = "tbConnString"; + this.tbConnString.Size = new System.Drawing.Size(598, 20); + this.tbConnString.TabIndex = 2; + this.tbConnString.Text = "Data Source=.;Initial Catalog=SQLServerInternals;Trusted_Connection=True"; + // + // btnBulkCopy + // + this.btnBulkCopy.Location = new System.Drawing.Point(16, 300); + this.btnBulkCopy.Name = "btnBulkCopy"; + this.btnBulkCopy.Size = new System.Drawing.Size(137, 23); + this.btnBulkCopy.TabIndex = 9; + this.btnBulkCopy.Text = "Bulk Copy"; + this.btnBulkCopy.UseVisualStyleBackColor = true; + this.btnBulkCopy.Click += new System.EventHandler(this.btnBulkCopy_Click); + // + // lblSeparateInsertInfo + // + this.lblSeparateInsertInfo.AutoSize = true; + this.lblSeparateInsertInfo.Location = new System.Drawing.Point(159, 112); + this.lblSeparateInsertInfo.Name = "lblSeparateInsertInfo"; + this.lblSeparateInsertInfo.Size = new System.Drawing.Size(323, 13); + this.lblSeparateInsertInfo.TabIndex = 10; + this.lblSeparateInsertInfo.Text = "Insert data in separate INSERT statements in the single transaction"; + // + // lblTVPInfo + // + this.lblTVPInfo.AutoSize = true; + this.lblTVPInfo.Location = new System.Drawing.Point(159, 141); + this.lblTVPInfo.Name = "lblTVPInfo"; + this.lblTVPInfo.Size = new System.Drawing.Size(249, 13); + this.lblTVPInfo.TabIndex = 11; + this.lblTVPInfo.Text = "Insert batch of rows using TVP (SQL Server 2008+)"; + // + // lblElementCentricXMLInfo + // + this.lblElementCentricXMLInfo.AutoSize = true; + this.lblElementCentricXMLInfo.Location = new System.Drawing.Point(159, 170); + this.lblElementCentricXMLInfo.Name = "lblElementCentricXMLInfo"; + this.lblElementCentricXMLInfo.Size = new System.Drawing.Size(302, 13); + this.lblElementCentricXMLInfo.TabIndex = 12; + this.lblElementCentricXMLInfo.Text = "Using Element-Cenric XML as parameter parsing it with XQuery"; + // + // lblAttributeCentricXMLInfo + // + this.lblAttributeCentricXMLInfo.AutoSize = true; + this.lblAttributeCentricXMLInfo.Location = new System.Drawing.Point(159, 199); + this.lblAttributeCentricXMLInfo.Name = "lblAttributeCentricXMLInfo"; + this.lblAttributeCentricXMLInfo.Size = new System.Drawing.Size(303, 13); + this.lblAttributeCentricXMLInfo.TabIndex = 13; + this.lblAttributeCentricXMLInfo.Text = "Using Attribute-Cenric XML as parameter parsing it with XQuery"; + // + // lblOpenXMLInfo + // + this.lblOpenXMLInfo.AutoSize = true; + this.lblOpenXMLInfo.Location = new System.Drawing.Point(159, 229); + this.lblOpenXMLInfo.Name = "lblOpenXMLInfo"; + this.lblOpenXMLInfo.Size = new System.Drawing.Size(154, 13); + this.lblOpenXMLInfo.TabIndex = 14; + this.lblOpenXMLInfo.Text = "Using OPENXML to parse data"; + // + // lblAttributeCentricTempTableInfo + // + this.lblAttributeCentricTempTableInfo.AutoSize = true; + this.lblAttributeCentricTempTableInfo.Location = new System.Drawing.Point(159, 267); + this.lblAttributeCentricTempTableInfo.Name = "lblAttributeCentricTempTableInfo"; + this.lblAttributeCentricTempTableInfo.Size = new System.Drawing.Size(276, 26); + this.lblAttributeCentricTempTableInfo.TabIndex = 15; + this.lblAttributeCentricTempTableInfo.Text = "Using Atttribute-Centric XML parsing it with XQuery using \r\ntemporary table to re" + + "duce locking"; + // + // lblSQLBulkCopyInfo + // + this.lblSQLBulkCopyInfo.AutoSize = true; + this.lblSQLBulkCopyInfo.Location = new System.Drawing.Point(159, 305); + this.lblSQLBulkCopyInfo.Name = "lblSQLBulkCopyInfo"; + this.lblSQLBulkCopyInfo.Size = new System.Drawing.Size(130, 13); + this.lblSQLBulkCopyInfo.TabIndex = 16; + this.lblSQLBulkCopyInfo.Text = "Using SQLBulkCopy class"; + // + // lblURL + // + this.lblURL.AutoSize = true; + this.lblURL.Location = new System.Drawing.Point(535, 343); + this.lblURL.Name = "lblURL"; + this.lblURL.Size = new System.Drawing.Size(130, 13); + this.lblURL.TabIndex = 17; + this.lblURL.TabStop = true; + this.lblURL.Text = "http://aboutsqlserver.com"; + this.lblURL.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lblURL_LinkClicked); + // + // labelBookInfo + // + this.labelBookInfo.AutoSize = true; + this.labelBookInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelBookInfo.Location = new System.Drawing.Point(126, 343); + this.labelBookInfo.Name = "labelBookInfo"; + this.labelBookInfo.Size = new System.Drawing.Size(155, 13); + this.labelBookInfo.TabIndex = 18; + this.labelBookInfo.Text = "PRO SQL Server Internals"; + // + // lblInfo2 + // + this.lblInfo2.AutoSize = true; + this.lblInfo2.Location = new System.Drawing.Point(287, 343); + this.lblInfo2.Name = "lblInfo2"; + this.lblInfo2.Size = new System.Drawing.Size(249, 13); + this.lblInfo2.TabIndex = 19; + this.lblInfo2.Text = "companion materials. Written by Dmitri Korotkevitch"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.Location = new System.Drawing.Point(13, 9); + this.label1.MaximumSize = new System.Drawing.Size(794, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(786, 48); + this.label1.TabIndex = 20; + this.label1.Text = resources.GetString("label1.Text"); + this.label1.TextAlign = System.Drawing.ContentAlignment.TopCenter; + // + // lblSiResult + // + this.lblSiResult.AutoSize = true; + this.lblSiResult.ForeColor = System.Drawing.Color.Red; + this.lblSiResult.Location = new System.Drawing.Point(520, 112); + this.lblSiResult.Name = "lblSiResult"; + this.lblSiResult.Size = new System.Drawing.Size(0, 13); + this.lblSiResult.TabIndex = 21; + // + // lblTVPResult + // + this.lblTVPResult.AutoSize = true; + this.lblTVPResult.ForeColor = System.Drawing.Color.Red; + this.lblTVPResult.Location = new System.Drawing.Point(520, 141); + this.lblTVPResult.Name = "lblTVPResult"; + this.lblTVPResult.Size = new System.Drawing.Size(0, 13); + this.lblTVPResult.TabIndex = 22; + // + // lblECXMLResult + // + this.lblECXMLResult.AutoSize = true; + this.lblECXMLResult.ForeColor = System.Drawing.Color.Red; + this.lblECXMLResult.Location = new System.Drawing.Point(520, 170); + this.lblECXMLResult.Name = "lblECXMLResult"; + this.lblECXMLResult.Size = new System.Drawing.Size(0, 13); + this.lblECXMLResult.TabIndex = 23; + // + // lblACXMLResult + // + this.lblACXMLResult.AutoSize = true; + this.lblACXMLResult.ForeColor = System.Drawing.Color.Red; + this.lblACXMLResult.Location = new System.Drawing.Point(520, 199); + this.lblACXMLResult.Name = "lblACXMLResult"; + this.lblACXMLResult.Size = new System.Drawing.Size(0, 13); + this.lblACXMLResult.TabIndex = 24; + // + // lblOXMLResult + // + this.lblOXMLResult.AutoSize = true; + this.lblOXMLResult.ForeColor = System.Drawing.Color.Red; + this.lblOXMLResult.Location = new System.Drawing.Point(520, 229); + this.lblOXMLResult.Name = "lblOXMLResult"; + this.lblOXMLResult.Size = new System.Drawing.Size(0, 13); + this.lblOXMLResult.TabIndex = 25; + // + // lblACTTXMLResult + // + this.lblACTTXMLResult.AutoSize = true; + this.lblACTTXMLResult.ForeColor = System.Drawing.Color.Red; + this.lblACTTXMLResult.Location = new System.Drawing.Point(520, 267); + this.lblACTTXMLResult.Name = "lblACTTXMLResult"; + this.lblACTTXMLResult.Size = new System.Drawing.Size(0, 13); + this.lblACTTXMLResult.TabIndex = 26; + // + // lblBCResult + // + this.lblBCResult.AutoSize = true; + this.lblBCResult.ForeColor = System.Drawing.Color.Red; + this.lblBCResult.Location = new System.Drawing.Point(520, 305); + this.lblBCResult.Name = "lblBCResult"; + this.lblBCResult.Size = new System.Drawing.Size(0, 13); + this.lblBCResult.TabIndex = 27; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(814, 362); + this.Controls.Add(this.lblBCResult); + this.Controls.Add(this.lblACTTXMLResult); + this.Controls.Add(this.lblOXMLResult); + this.Controls.Add(this.lblACXMLResult); + this.Controls.Add(this.lblECXMLResult); + this.Controls.Add(this.lblTVPResult); + this.Controls.Add(this.lblSiResult); + this.Controls.Add(this.label1); + this.Controls.Add(this.lblInfo2); + this.Controls.Add(this.labelBookInfo); + this.Controls.Add(this.lblURL); + this.Controls.Add(this.lblSQLBulkCopyInfo); + this.Controls.Add(this.lblAttributeCentricTempTableInfo); + this.Controls.Add(this.lblOpenXMLInfo); + this.Controls.Add(this.lblAttributeCentricXMLInfo); + this.Controls.Add(this.lblElementCentricXMLInfo); + this.Controls.Add(this.lblTVPInfo); + this.Controls.Add(this.lblSeparateInsertInfo); + this.Controls.Add(this.btnBulkCopy); + this.Controls.Add(this.tbConnString); + this.Controls.Add(this.btnAttributeCentricTempTable); + this.Controls.Add(this.btnOpenXml); + this.Controls.Add(this.btnAttributeCentric); + this.Controls.Add(this.btnElementCentric); + this.Controls.Add(this.btnTvp); + this.Controls.Add(this.btnSeparateInserts); + this.Controls.Add(this.tbPacketSize); + this.Controls.Add(this.lblPacketSize); + this.MaximizeBox = false; + this.Name = "MainForm"; + this.Text = "Saving Batch of Rows"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblPacketSize; + private System.Windows.Forms.TextBox tbPacketSize; + private System.Windows.Forms.Button btnSeparateInserts; + private System.Windows.Forms.Button btnTvp; + private System.Windows.Forms.Button btnElementCentric; + private System.Windows.Forms.Button btnAttributeCentric; + private System.Windows.Forms.Button btnOpenXml; + private System.Windows.Forms.Button btnAttributeCentricTempTable; + private System.Windows.Forms.TextBox tbConnString; + private System.Windows.Forms.Button btnBulkCopy; + private System.Windows.Forms.Label lblSeparateInsertInfo; + private System.Windows.Forms.Label lblTVPInfo; + private System.Windows.Forms.Label lblElementCentricXMLInfo; + private System.Windows.Forms.Label lblAttributeCentricXMLInfo; + private System.Windows.Forms.Label lblOpenXMLInfo; + private System.Windows.Forms.Label lblAttributeCentricTempTableInfo; + private System.Windows.Forms.Label lblSQLBulkCopyInfo; + private System.Windows.Forms.LinkLabel lblURL; + private System.Windows.Forms.Label labelBookInfo; + private System.Windows.Forms.Label lblInfo2; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label lblSiResult; + private System.Windows.Forms.Label lblTVPResult; + private System.Windows.Forms.Label lblECXMLResult; + private System.Windows.Forms.Label lblACXMLResult; + private System.Windows.Forms.Label lblOXMLResult; + private System.Windows.Forms.Label lblACTTXMLResult; + private System.Windows.Forms.Label lblBCResult; + } +} + diff --git a/.Net/SaveRecordSetApp/MainForm.cs b/.Net/SaveRecordSetApp/MainForm.cs new file mode 100644 index 0000000..b313d87 --- /dev/null +++ b/.Net/SaveRecordSetApp/MainForm.cs @@ -0,0 +1,312 @@ +/****************************************************************************/ +/* Pro SQL Server Internals */ +/* APress. 1st Edition. ISBN-13: 978-1430259626 ISBN-10:1430259620 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dmitri@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 12. Temporary Tables */ +/* Saving Batch of Rows from Client Application */ +/****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Data.SqlClient; +using System.Diagnostics; + +namespace SaveRecordSetApp +{ + public partial class MainForm : Form + { + public MainForm() + { + InitializeComponent(); + if (System.Configuration.ConfigurationManager.ConnectionStrings["ConnStr"] != null) + tbConnString.Text = System.Configuration.ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString; + } + + private int GetPacketSize() + { + int result; + if (!Int32.TryParse(tbPacketSize.Text, out result)) + { + MessageBox.Show("Invalid packet size. Using 5000", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return 5000; + } + return result; + } + + private SqlConnection GetConnection() + { + SqlConnection conn = new SqlConnection(tbConnString.Text); + conn.Open(); + return conn; + } + + private bool IsTVPSupported() + { + using (SqlConnection conn = GetConnection()) + { + SqlCommand cmd = new SqlCommand(@"select @Ver = convert(int, left(convert(nvarchar(128), serverproperty('ProductVersion')), + charindex('.',convert(nvarchar(128), serverproperty('ProductVersion'))) - 1))", conn); + cmd.Parameters.Add("@Ver", SqlDbType.Int).Direction = ParameterDirection.Output; + cmd.ExecuteNonQuery(); + return (int)(cmd.Parameters[0].Value) > 9; + } + } + + + private void TruncateTable() + { + using (SqlConnection conn = GetConnection()) + { + SqlCommand cmd = new SqlCommand("truncate table dbo.DataRecords", conn); + cmd.ExecuteNonQuery(); + } + } + + private void btnSeparateInserts_Click(object sender, EventArgs e) + { + TimeSpan workTime; + int packetSize = GetPacketSize(); + + TruncateTable(); + using (SqlConnection conn = GetConnection()) + { + DateTime startTime = DateTime.Now; + SqlCommand insertCmd = new SqlCommand( + @"insert into dbo.DataRecords(ID,Col1,Col2,Col3,Col4,Col5, + Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13, + Col14,Col15,Col16,Col17,Col18,Col19,Col20) + values(@ID,@Col1,@Col2,@Col3,@Col4,@Col5 + ,@Col6,@Col7,@Col8,@Col9,@Col10,@Col11,@Col12,@Col13 + ,@Col14,@Col15,@Col16,@Col17,@Col18,@Col19,@Col20)",conn); + insertCmd.Parameters.Add("@ID", SqlDbType.Int); + for (int i = 1; i <= 20; i++) + insertCmd.Parameters.Add("@Col" + i.ToString(), SqlDbType.VarChar, 20); + using (SqlTransaction tran = conn.BeginTransaction(IsolationLevel.ReadCommitted)) + { + try + { + insertCmd.Transaction = tran; + + for (int i = 0; i < packetSize; i++) + { + insertCmd.Parameters[0].Value = i; + for (int p = 1; p <= 20; p++) + insertCmd.Parameters[p].Value = "Parameter: " + p.ToString(); + insertCmd.ExecuteNonQuery(); + } + tran.Commit(); + } + catch (Exception ex) + { + tran.Rollback(); + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + workTime = DateTime.Now - startTime; + } + MessageBox.Show(lblSiResult.Text = String.Format("Execution Time: {0} ms",(int)workTime.TotalMilliseconds), + "Execution Statistics", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void btnTvp_Click(object sender, EventArgs e) + { + if (!IsTVPSupported()) + { + MessageBox.Show(lblTVPResult.Text = "You should have SQL Server 2008+ to use TVP", + "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + TimeSpan workTime1, workTime2; + int packetSize = GetPacketSize(); + + TruncateTable(); + using (SqlConnection conn = GetConnection()) + { + DateTime startTime = DateTime.Now; + DataTable table = new DataTable(); + table.Columns.Add("ID", typeof(Int32)); + for (int i = 1; i <= 20; i++) + table.Columns.Add("Col" + i.ToString(), typeof(string)); + for (int i = 0; i < packetSize; i++) + table.Rows.Add(i, "Parameter: 1", "Parameter: 2", "Parameter: 3", + "Parameter: 4", "Parameter: 5", "Parameter: 6", "Parameter: 7", + "Parameter: 8", "Parameter: 9", "Parameter: 10", "Parameter: 11", + "Parameter: 12", "Parameter: 13", "Parameter: 14", "Parameter: 15", + "Parameter: 16", "Parameter: 17", "Parameter: 18", "Parameter: 19", + "Parameter: 20"); + workTime1 = DateTime.Now - startTime; + SqlCommand insertCmd = new SqlCommand("dbo.InsertDataRecordsTVP", conn); + insertCmd.Parameters.Add("@Data", SqlDbType.Structured); + insertCmd.Parameters[0].TypeName = "dbo.DataRecordsTVP"; + insertCmd.Parameters[0].Value = table; + insertCmd.ExecuteNonQuery(); + workTime2 = DateTime.Now - startTime; + } + MessageBox.Show( + lblTVPResult.Text = + String.Format("Preparation Time: {0} ms; Execution Time: {1} ms", (int)workTime1.TotalMilliseconds,(int)workTime2.TotalMilliseconds), + "Execution Statistics", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private string PrepareElementCentricXml(int packetSize) + { + StringBuilder sb = new StringBuilder(""); + for (int i = 0; i < packetSize; i++) + sb.AppendFormat( +@"{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}" + +@"{11}{12}{13}{14}{15}{16}{17}{18}{19}{20}", +i, "Parameter: 1", "Parameter: 2", "Parameter: 3","Parameter: 4", "Parameter: 5", "Parameter: 6", "Parameter: 7","Parameter: 8", "Parameter: 9", "Parameter: 10", +"Parameter: 11","Parameter: 12", "Parameter: 13", "Parameter: 14", "Parameter: 15","Parameter: 16", "Parameter: 17", "Parameter: 18", "Parameter: 19", + "Parameter: 20"); + sb.Append(""); + return sb.ToString(); + } + + + private void btnElementCentric_Click(object sender, EventArgs e) + { + TimeSpan workTime1, workTime2; + int packetSize = GetPacketSize(); + + TruncateTable(); + DateTime startTime = DateTime.Now; + string xml = PrepareElementCentricXml(packetSize); + workTime1 = DateTime.Now - startTime; + using (SqlConnection conn = GetConnection()) + { + SqlCommand insertCmd = new SqlCommand("dbo.InsertDataRecordsElementsXml", conn); + insertCmd.CommandType = CommandType.StoredProcedure; + insertCmd.Parameters.Add("@Data", SqlDbType.Xml); + insertCmd.Parameters[0].Value = xml; + insertCmd.CommandTimeout = 0; + insertCmd.ExecuteNonQuery(); + workTime2 = DateTime.Now - startTime; + } + MessageBox.Show( + lblECXMLResult.Text = + String.Format("Preparation Time: {0} ms; Execution Time: {1} ms", (int)workTime1.TotalMilliseconds, (int)workTime2.TotalMilliseconds), + "Execution Statistics", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + + private string PrepareAttributeCentricXml(int packetSize) + { + StringBuilder sb = new StringBuilder(""); + for (int i = 0; i < packetSize; i++) + sb.AppendFormat( +"", +i, "Parameter: 1", "Parameter: 2", "Parameter: 3", "Parameter: 4", "Parameter: 5", "Parameter: 6", "Parameter: 7", "Parameter: 8", "Parameter: 9", "Parameter: 10", +"Parameter: 11", "Parameter: 12", "Parameter: 13", "Parameter: 14", "Parameter: 15", "Parameter: 16", "Parameter: 17", "Parameter: 18", "Parameter: 19", + "Parameter: 20"); + sb.Append(""); + return sb.ToString(); + } + + private void btnAttributeCentric_Click(object sender, EventArgs e) + { + TimeSpan workTime1, workTime2; + int packetSize = GetPacketSize(); + + TruncateTable(); + DateTime startTime = DateTime.Now; + string xml = PrepareAttributeCentricXml(packetSize); + workTime1 = DateTime.Now - startTime; + using (SqlConnection conn = GetConnection()) + { + SqlCommand insertCmd = new SqlCommand( + (sender == btnAttributeCentric) ? "dbo.InsertDataRecordsAttrXml" : "dbo.InsertDataRecordsAttrXml2", conn); + insertCmd.CommandType = CommandType.StoredProcedure; + insertCmd.Parameters.Add("@Data", SqlDbType.Xml); + insertCmd.Parameters[0].Value = xml; + insertCmd.CommandTimeout = 0; + insertCmd.ExecuteNonQuery(); + workTime2 = DateTime.Now - startTime; + } + string s = String.Format("Preparation Time: {0} ms; Execution Time: {1} ms", (int)workTime1.TotalMilliseconds, (int)workTime2.TotalMilliseconds); + if (sender == btnAttributeCentric) + lblACXMLResult.Text = s; + else + lblACTTXMLResult.Text = s; + MessageBox.Show(s,"Execution Statistics", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + + private void btnOpenXml_Click(object sender, EventArgs e) + { + TimeSpan workTime1, workTime2; + int packetSize = GetPacketSize(); + + TruncateTable(); + DateTime startTime = DateTime.Now; + string xml = PrepareAttributeCentricXml(packetSize); + workTime1 = DateTime.Now - startTime; + using (SqlConnection conn = GetConnection()) + { + SqlCommand insertCmd = new SqlCommand("dbo.InsertDataRecordsOpenXML", conn); + insertCmd.CommandType = CommandType.StoredProcedure; + insertCmd.Parameters.Add("@Data", SqlDbType.Xml); + insertCmd.Parameters[0].Value = xml; + insertCmd.ExecuteNonQuery(); + workTime2 = DateTime.Now - startTime; + } + MessageBox.Show( + lblOXMLResult.Text = + String.Format("Preparation Time: {0} ms; Execution Time: {1} ms", (int)workTime1.TotalMilliseconds, (int)workTime2.TotalMilliseconds), + "Execution Statistics", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void btnBulkCopy_Click(object sender, EventArgs e) + { + TimeSpan workTime1, workTime2; + int packetSize = GetPacketSize(); + + TruncateTable(); + using (SqlConnection conn = GetConnection()) + { + DateTime startTime = DateTime.Now; + DataTable table = new DataTable(); + table.Columns.Add("ID", typeof(Int32)); + for (int i = 1; i <= 20; i++) + table.Columns.Add("Col" + i.ToString(), typeof(string)); + for (int i = 0; i < packetSize; i++) + table.Rows.Add(i, "Parameter: 1", "Parameter: 2", "Parameter: 3", + "Parameter: 4", "Parameter: 5", "Parameter: 6", "Parameter: 7", + "Parameter: 8", "Parameter: 9", "Parameter: 10", "Parameter: 11", + "Parameter: 12", "Parameter: 13", "Parameter: 14", "Parameter: 15", + "Parameter: 16", "Parameter: 17", "Parameter: 18", "Parameter: 19", + "Parameter: 20"); + workTime1 = DateTime.Now - startTime; + using (SqlBulkCopy bc = new SqlBulkCopy(conn)) + { + bc.BatchSize = packetSize; + bc.DestinationTableName = "dbo.DataRecords"; + bc.WriteToServer(table); + } + workTime2 = DateTime.Now - startTime; + } + MessageBox.Show( + lblBCResult.Text = + String.Format("Preparation Time: {0} ms; Execution Time: {1} ms", (int)workTime1.TotalMilliseconds, (int)workTime2.TotalMilliseconds), + "Execution Statistics", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void lblURL_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + ProcessStartInfo sInfo = new ProcessStartInfo("http://aboutsqlserver.com"); + Process.Start(sInfo); + } + + } +} diff --git a/.Net/SaveRecordSetApp/MainForm.resx b/.Net/SaveRecordSetApp/MainForm.resx new file mode 100644 index 0000000..cc378d2 --- /dev/null +++ b/.Net/SaveRecordSetApp/MainForm.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Application compares performance of the various methods that insert batch of rows to the database. Results vary based on packet size and if you run application locally or over network. +Application uses database objects created by "07.TVP - Batch Insert.sql" script file from "12.Chapter 12 (Temp Tables)" SQL project. + + \ No newline at end of file diff --git a/.Net/SaveRecordSetApp/Program.cs b/.Net/SaveRecordSetApp/Program.cs new file mode 100644 index 0000000..29b904f --- /dev/null +++ b/.Net/SaveRecordSetApp/Program.cs @@ -0,0 +1,32 @@ +/****************************************************************************/ +/* Pro SQL Server Internals */ +/* APress. 1st Edition. ISBN-13: 978-1430259626 ISBN-10:1430259620 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dmitri@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 12. Temporary Tables */ +/* Saving Batch of Rows from Client Application */ +/****************************************************************************/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace SaveRecordSetApp +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} diff --git a/.Net/SaveRecordSetApp/Properties/AssemblyInfo.cs b/.Net/SaveRecordSetApp/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..22f7171 --- /dev/null +++ b/.Net/SaveRecordSetApp/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SaveRecordSetApp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("SaveRecordSetApp")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("99f91cae-13f3-4cd0-9fba-847f0545d42e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/.Net/SaveRecordSetApp/Properties/Resources.Designer.cs b/.Net/SaveRecordSetApp/Properties/Resources.Designer.cs new file mode 100644 index 0000000..bba4bc5 --- /dev/null +++ b/.Net/SaveRecordSetApp/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SaveRecordSetApp.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SaveRecordSetApp.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/.Net/SaveRecordSetApp/Properties/Resources.resx b/.Net/SaveRecordSetApp/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/.Net/SaveRecordSetApp/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/.Net/SaveRecordSetApp/Properties/Settings.Designer.cs b/.Net/SaveRecordSetApp/Properties/Settings.Designer.cs new file mode 100644 index 0000000..99ab917 --- /dev/null +++ b/.Net/SaveRecordSetApp/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SaveRecordSetApp.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/.Net/SaveRecordSetApp/Properties/Settings.settings b/.Net/SaveRecordSetApp/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/.Net/SaveRecordSetApp/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.Net/SaveRecordSetApp/SaveRecordSetApp.csproj b/.Net/SaveRecordSetApp/SaveRecordSetApp.csproj new file mode 100644 index 0000000..1a768cb --- /dev/null +++ b/.Net/SaveRecordSetApp/SaveRecordSetApp.csproj @@ -0,0 +1,94 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {49EAE681-0A5A-4897-B9A6-AE876CACB201} + WinExe + Properties + SaveRecordSetApp + SaveRecordSetApp + v4.5 + 512 + true + false + + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + false + + + + + + + + + + + + + + + + Form + + + MainForm.cs + + + + + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + \ No newline at end of file diff --git a/.Net/SaveRecordSetApp/app.config b/.Net/SaveRecordSetApp/app.config new file mode 100644 index 0000000..df7ed6d --- /dev/null +++ b/.Net/SaveRecordSetApp/app.config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.exe b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.exe new file mode 100644 index 0000000..70d51bc Binary files /dev/null and b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.exe differ diff --git a/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.exe.config b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.exe.config new file mode 100644 index 0000000..df7ed6d --- /dev/null +++ b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.exe.config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.pdb b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.pdb new file mode 100644 index 0000000..702a4f8 Binary files /dev/null and b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.pdb differ diff --git a/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.vshost.exe b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.vshost.exe new file mode 100644 index 0000000..c0dfecc Binary files /dev/null and b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.vshost.exe differ diff --git a/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.vshost.exe.config b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.vshost.exe.config new file mode 100644 index 0000000..7d5c098 --- /dev/null +++ b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.vshost.exe.config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.vshost.exe.manifest b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.vshost.exe.manifest new file mode 100644 index 0000000..061c9ca --- /dev/null +++ b/.Net/SaveRecordSetApp/bin/Debug/SaveRecordSetApp.vshost.exe.manifest @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/DesignTimeResolveAssemblyReferences.cache b/.Net/SaveRecordSetApp/obj/x86/Debug/DesignTimeResolveAssemblyReferences.cache new file mode 100644 index 0000000..429c746 Binary files /dev/null and b/.Net/SaveRecordSetApp/obj/x86/Debug/DesignTimeResolveAssemblyReferences.cache differ diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/.Net/SaveRecordSetApp/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000..66552eb Binary files /dev/null and b/.Net/SaveRecordSetApp/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.Form1.resources b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.Form1.resources new file mode 100644 index 0000000..06c24d0 Binary files /dev/null and b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.Form1.resources differ diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.MainForm.resources b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.MainForm.resources new file mode 100644 index 0000000..c47d38c Binary files /dev/null and b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.MainForm.resources differ diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.Properties.Resources.resources b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.Properties.Resources.resources new file mode 100644 index 0000000..6c05a97 Binary files /dev/null and b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.Properties.Resources.resources differ diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.csproj.FileListAbsolute.txt b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..7cb1778 --- /dev/null +++ b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.csproj.FileListAbsolute.txt @@ -0,0 +1,31 @@ +Z:\__Work\Blog\SaveRecordSet\SaveRecordSetApp\obj\x86\Debug\ResolveAssemblyReference.cache +Z:\__Work\Blog\SaveRecordSet\SaveRecordSetApp\bin\Debug\SaveRecordSetApp.exe +Z:\__Work\Blog\SaveRecordSet\SaveRecordSetApp\bin\Debug\SaveRecordSetApp.pdb +Z:\__Work\Blog\SaveRecordSet\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.Form1.resources +Z:\__Work\Blog\SaveRecordSet\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.Properties.Resources.resources +Z:\__Work\Blog\SaveRecordSet\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.exe +Z:\__Work\Blog\SaveRecordSet\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.pdb +c:\Work\Docs\.B\Precon\C#\SaveRecordSet\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.exe +c:\Work\Docs\.B\Precon\C#\SaveRecordSet\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.pdb +c:\Work\Docs\.B\Precon\C#\SaveRecordSet\SaveRecordSetApp\bin\Debug\SaveRecordSetApp.exe +c:\Work\Docs\.B\Precon\C#\SaveRecordSet\SaveRecordSetApp\bin\Debug\SaveRecordSetApp.pdb +c:\Work\Docs\.B\Precon\C#\SaveRecordSet\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.Form1.resources +c:\Work\Docs\.B\Precon\C#\SaveRecordSet\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.Properties.Resources.resources +c:\Work\Docs\.B\Precon\C#\SaveRecordSet\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.csproj.GenerateResource.Cache +C:\Work\SaveBacth\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.exe +C:\Work\SaveBacth\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.pdb +C:\Work\SaveBacth\SaveRecordSetApp\bin\Debug\SaveRecordSetApp.exe +C:\Work\SaveBacth\SaveRecordSetApp\bin\Debug\SaveRecordSetApp.pdb +C:\Work\SaveBacth\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.csprojResolveAssemblyReference.cache +C:\Work\SaveBacth\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.Form1.resources +C:\Work\SaveBacth\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.Properties.Resources.resources +C:\Work\SaveBacth\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.csproj.GenerateResource.Cache +c:\.Work\SQL Server Internals\.Net\12.Chapter 12 (Temporary Tables)\SaveRecordSetApp\bin\Debug\SaveRecordSetApp.exe.config +c:\.Work\SQL Server Internals\.Net\12.Chapter 12 (Temporary Tables)\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.exe +c:\.Work\SQL Server Internals\.Net\12.Chapter 12 (Temporary Tables)\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.pdb +c:\.Work\SQL Server Internals\.Net\12.Chapter 12 (Temporary Tables)\SaveRecordSetApp\bin\Debug\SaveRecordSetApp.exe +c:\.Work\SQL Server Internals\.Net\12.Chapter 12 (Temporary Tables)\SaveRecordSetApp\bin\Debug\SaveRecordSetApp.pdb +c:\.Work\SQL Server Internals\.Net\12.Chapter 12 (Temporary Tables)\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.csprojResolveAssemblyReference.cache +c:\.Work\SQL Server Internals\.Net\12.Chapter 12 (Temporary Tables)\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.MainForm.resources +c:\.Work\SQL Server Internals\.Net\12.Chapter 12 (Temporary Tables)\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.Properties.Resources.resources +c:\.Work\SQL Server Internals\.Net\12.Chapter 12 (Temporary Tables)\SaveRecordSetApp\obj\x86\Debug\SaveRecordSetApp.csproj.GenerateResource.Cache diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.csproj.GenerateResource.Cache b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.csproj.GenerateResource.Cache new file mode 100644 index 0000000..64bf36d Binary files /dev/null and b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.csproj.GenerateResource.Cache differ diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.csprojResolveAssemblyReference.cache b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.csprojResolveAssemblyReference.cache new file mode 100644 index 0000000..1ff4f9f Binary files /dev/null and b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.csprojResolveAssemblyReference.cache differ diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.exe b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.exe new file mode 100644 index 0000000..70d51bc Binary files /dev/null and b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.exe differ diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.pdb b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.pdb new file mode 100644 index 0000000..702a4f8 Binary files /dev/null and b/.Net/SaveRecordSetApp/obj/x86/Debug/SaveRecordSetApp.pdb differ diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/TempPE/Properties.Resources.Designer.cs.dll b/.Net/SaveRecordSetApp/obj/x86/Debug/TempPE/Properties.Resources.Designer.cs.dll new file mode 100644 index 0000000..b0e393f Binary files /dev/null and b/.Net/SaveRecordSetApp/obj/x86/Debug/TempPE/Properties.Resources.Designer.cs.dll differ diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs b/.Net/SaveRecordSetApp/obj/x86/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs b/.Net/SaveRecordSetApp/obj/x86/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs new file mode 100644 index 0000000..e69de29 diff --git a/.Net/SaveRecordSetApp/obj/x86/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs b/.Net/SaveRecordSetApp/obj/x86/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs new file mode 100644 index 0000000..e69de29 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1e9f8f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.dat filter=lfs diff=lfs merge=lfs -text diff --git a/9781484211373.jpg b/9781484211373.jpg new file mode 100644 index 0000000..368fbd1 Binary files /dev/null and b/9781484211373.jpg differ diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..c8d109c --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,27 @@ +Freeware License, some rights reserved + +Copyright (c) 2015 Dmitri Korotkevitch + +Permission is hereby granted, free of charge, to anyone obtaining a copy +of this software and associated documentation files (the "Software"), +to work with the Software within the limits of freeware distribution and fair use. +This includes the rights to use, copy, and modify the Software for personal use. +Users are also allowed and encouraged to submit corrections and modifications +to the Software for the benefit of other users. + +It is not allowed to reuse, modify, or redistribute the Software for +commercial use in any way, or for a user’s educational materials such as books +or blog articles without prior permission from the copyright holder. + +The above copyright notice and this permission notice need to be included +in all copies or substantial portions of the software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..3d1811b --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +#Apress Source Code + +This repository accompanies [*Expert SQL Server in-Memory OLTP*](http://www.apress.com/9781484211373) by Dmitri Korotkevitch (Apress, 2015). + +![Cover image](9781484211373.jpg) + +Download the files as a zip using the green button, or clone the repository to your machine using Git. + +##Releases + +Release v1.0 corresponds to the code in the published book, without corrections or updates. + +##Contributions + +See the file Contributing.md for more information on how you can contribute to this repository. diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/00.Init/00.Init.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/00.Init/00.Init.sql new file mode 100644 index 0000000..6a2fcea --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/00.Init/00.Init.sql @@ -0,0 +1,81 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Database Creation Script */ +/****************************************************************************/ +set noexec off +go + +use master +go + +if convert(int, + left( + convert(nvarchar(128), serverproperty('ProductVersion')), + charindex('.',convert(nvarchar(128), serverproperty('ProductVersion'))) - 1 + ) + ) < 12 +begin + raiserror('You should have SQL Server 2014 to execute this script',16,1) with nowait + set noexec on +end +go + +if convert(int, serverproperty('EngineEdition')) != 3 or charindex('X64',@@Version) = 0 +begin + raiserror('That script requires 64-Bit Enterprise Edition of SQL Server to run',16,1) + set noexec on +end +go + +if exists +( + select * from sys.databases where name = 'InMemoryOLTP2014' +) +begin + raiserror('Database [InMemoryOLTP2014] already created',16,1) + set noexec on +end +go + + + +declare + @dataPath nvarchar(512) = convert(nvarchar(512),serverproperty('InstanceDefaultDataPath')) + ,@logPath nvarchar(512) = convert(nvarchar(512),serverproperty('InstanceDefaultLogPath')) + +/*** REPLACE IF YOU WANT TO STORE IN-MEMORY OLTP FILES IN THE DIFFERENT PLACE ***/ +declare + @HKPath nvarchar(512) = @dataPath + 'InMemoryOLTP2014_HKData' + +declare + @SQL nvarchar(max) + +select @SQL = +N'create database [InMemoryOLTP2014] on +primary (name=N''InMemoryOLTP2014'', filename=N''' + @dataPath + N'InMemoryOLTP2014.mdf'', size=102400KB, filegrowth = 102400KB), +filegroup [HKData] contains memory_optimized_data (name=N''InMemoryOLTP2014_HekatonData'', filename=N''' + @HKPath + N'''), +filegroup LOGDATA +(name = N''LogData1'', filename=N''' + @dataPath + N'InMemoryOLTP2014LogData1.ndf''), +(name = N''LogData2'', filename=N''' + @dataPath + N'InMemoryOLTP2014LogData2.ndf''), +(name = N''LogData3'', filename=N''' + @dataPath + N'InMemoryOLTP2014LogData3.ndf''), +(name = N''LogData4'', filename=N''' + @dataPath + N'InMemoryOLTP2014LogData4.ndf'') +log on (name=N''InMemoryOLTP2014_log'', filename=N''' + @logPath + N'InMemoryOLTP2014.ldf'', size=256000KB, filegrowth = 256000KB); + +alter database [InMemoryOLTP2014] set recovery simple;' + +raiserror('Creating database InMemoryOLTP2014',0,1) with nowait +raiserror('Data Path: %s',0,1,@dataPath) with nowait +raiserror('Log Path: %s',0,1,@logPath) with nowait +raiserror('In-Memory OLTP Folder: %s',0,1,@HKPath) with nowait +raiserror('Statement:',0,1) with nowait +raiserror(@sql,0,1) with nowait + +exec sp_executesql @sql +go + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/00.Init/00.Init.ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/00.Init/00.Init.ssmssqlproj new file mode 100644 index 0000000..2f5efec --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/00.Init/00.Init.ssmssqlproj @@ -0,0 +1,21 @@ + + + + + + + + + + + + + 00.Init.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/02.Chapter 02 (In-Memory OLTP Objects)/01.Creating Memory-Optimized Objects.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/02.Chapter 02 (In-Memory OLTP Objects)/01.Creating Memory-Optimized Objects.sql new file mode 100644 index 0000000..e32ba77 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/02.Chapter 02 (In-Memory OLTP Objects)/01.Creating Memory-Optimized Objects.sql @@ -0,0 +1,265 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 02: In-Memory OLTP Objects */ +/* 01.Creating Memory-Optimized Objects */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +/****************************************************************************/ +/* Scripts in this chapter prepare the database schema for */ +/* LogRequestsGenerator demo app */ +/****************************************************************************/ + + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertRequestInfo_Memory' and s.name = 'dbo') drop proc dbo.InsertRequestInfo_Memory; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertRequestInfo_NativelyCompiled' and s.name = 'dbo') drop proc dbo.InsertRequestInfo_NativelyCompiled; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'WebRequests_Memory' and s.name = 'dbo') drop table dbo.WebRequests_Memory; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'WebRequestHeaders_Memory' and s.name = 'dbo') drop table dbo.WebRequestHeaders_Memory; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'WebRequestParams_Memory' and s.name = 'dbo') drop table dbo.WebRequestParams_Memory; +go + +create table dbo.WebRequests_Memory +( + RequestId int not null identity(1,1) + primary key nonclustered + hash with (bucket_count=262144), + RequestTime datetime2(4) not null + constraint DEF_WebRequests_Memory_RequestTime + default sysutcdatetime(), + URL varchar(255) not null, + RequestType tinyint not null, -- GET/POST/PUT + ClientIP varchar(15) + collate Latin1_General_100_BIN2 not null, + BytesReceived int not null, + + index IDX_RequestTime nonclustered(RequestTime) +) +with (memory_optimized=on, durability=schema_and_data) +go + +create table dbo.WebRequestHeaders_Memory +( + RequestHeaderId int not null identity(1,1) + primary key nonclustered + hash with (bucket_count=2097152), + RequestId int not null, + HeaderName varchar(64) not null, + HeaderValue varchar(256) not null, + + index IDX_RequestID nonclustered hash(RequestID) + with (bucket_count=262144) +) +with (memory_optimized=on, durability=schema_and_data) +go + +create table dbo.WebRequestParams_Memory +( + RequestParamId int not null identity(1,1) + primary key nonclustered + hash with (bucket_count=2097152), + RequestId int not null, + ParamName varchar(64) not null, + ParamValue nvarchar(256) not null, + + index IDX_RequestID nonclustered hash(RequestID) + with (bucket_count=262144) +) +with (memory_optimized=on, durability=schema_and_data) +go + +create proc dbo.InsertRequestInfo_Memory +( + @URL varchar(255) + ,@RequestType tinyint + ,@ClientIP varchar(15) + ,@BytesReceived int + -- Header fields + ,@Authorization varchar(256) + ,@UserAgent varchar(256) + ,@Host varchar(256) + ,@Connection varchar(256) + ,@Referer varchar(256) + -- Parameters.. Just for the demo purposes + ,@Param1 varchar(64) = null + ,@Param1Value nvarchar(256) = null + ,@Param2 varchar(64) = null + ,@Param2Value nvarchar(256) = null + ,@Param3 varchar(64) = null + ,@Param3Value nvarchar(256) = null + ,@Param4 varchar(64) = null + ,@Param4Value nvarchar(256) = null + ,@Param5 varchar(64) = null + ,@Param5Value nvarchar(256) = null +) +as +begin + set nocount on + set xact_abort on + + declare + @RequestId int + + begin tran + insert into dbo.WebRequests_Memory + (URL,RequestType,ClientIP,BytesReceived) + values + (@URL,@RequestType,@ClientIP,@BytesReceived); + + select @RequestId = SCOPE_IDENTITY(); + + insert into dbo.WebRequestHeaders_Memory + (RequestId,HeaderName,HeaderValue) + values + (@RequestId,'AUTHORIZATION',@Authorization) + ,(@RequestId,'USERAGENT',@UserAgent) + ,(@RequestId,'HOST',@Host) + ,(@RequestId,'CONNECTION',@Connection) + ,(@RequestId,'REFERER',@Referer); + + ;with Params(ParamName, ParamValue) + as + ( + select ParamName, ParamValue + from ( + values + (@Param1, @Param1Value) + ,(@Param2, @Param2Value) + ,(@Param3, @Param3Value) + ,(@Param4, @Param4Value) + ,(@Param5, @Param5Value) + ) v(ParamName, ParamValue) + where + ParamName is not null and + ParamValue is not null + ) + insert into dbo.WebRequestParams_Memory + (RequestID,ParamName,ParamValue) + select @RequestID, ParamName, ParamValue + from Params; + commit +end +go + + +create proc dbo.InsertRequestInfo_NativelyCompiled +( + @URL varchar(255) not null + ,@RequestType tinyint not null + ,@ClientIP varchar(15) not null + ,@BytesReceived int not null + -- Header fields + ,@Authorization varchar(256) not null + ,@UserAgent varchar(256) not null + ,@Host varchar(256) not null + ,@Connection varchar(256) not null + ,@Referer varchar(256) not null + -- Parameters.. Just for the demo purposes + ,@Param1 varchar(64) = null + ,@Param1Value nvarchar(256) = null + ,@Param2 varchar(64) = null + ,@Param2Value nvarchar(256) = null + ,@Param3 varchar(64) = null + ,@Param3Value nvarchar(256) = null + ,@Param4 varchar(64) = null + ,@Param4Value nvarchar(256) = null + ,@Param5 varchar(64) = null + ,@Param5Value nvarchar(256) = null +) +with native_compilation, schemabinding, execute as owner +as +begin atomic with +( + transaction isolation level = snapshot + ,language = N'English' +) + declare + @RequestId int + + insert into dbo.WebRequests_Memory + (URL,RequestType,ClientIP,BytesReceived) + values + (@URL,@RequestType,@ClientIP,@BytesReceived); + + select @RequestId = SCOPE_IDENTITY(); + + insert into dbo.WebRequestHeaders_Memory + (RequestId,HeaderName,HeaderValue) + values + (@RequestId,'AUTHORIZATION',@Authorization); + + insert into dbo.WebRequestHeaders_Memory + (RequestId,HeaderName,HeaderValue) + values + (@RequestId,'USERAGENT',@UserAgent); + + insert into dbo.WebRequestHeaders_Memory + (RequestId,HeaderName,HeaderValue) + values + (@RequestId,'HOST',@Host); + + insert into dbo.WebRequestHeaders_Memory + (RequestId,HeaderName,HeaderValue) + values + (@RequestId,'CONNECTION',@Connection); + + insert into dbo.WebRequestHeaders_Memory + (RequestId,HeaderName,HeaderValue) + values + (@RequestId,'REFERER',@Referer); + + if @Param1 collate Latin1_General_100_BIN2 is not null and + @Param1Value collate Latin1_General_100_BIN2 is not null + begin + insert into dbo.WebRequestParams_Memory + (RequestID,ParamName,ParamValue) + values + (@RequestId,@Param1,@Param1Value); + + if @Param2 collate Latin1_General_100_BIN2 is not null and + @Param2Value collate Latin1_General_100_BIN2 is not null + begin + insert into dbo.WebRequestParams_Memory + (RequestID,ParamName,ParamValue) + values + (@RequestId,@Param2,@Param2Value); + + if @Param3 collate Latin1_General_100_BIN2 is not null and + @Param3Value collate Latin1_General_100_BIN2 is not null + begin + insert into dbo.WebRequestParams_Memory + (RequestID,ParamName,ParamValue) + values + (@RequestId,@Param3,@Param3Value); + + if @Param4 collate Latin1_General_100_BIN2 is not null and + @Param4Value collate Latin1_General_100_BIN2 is not null + begin + insert into dbo.WebRequestParams_Memory + (RequestID,ParamName,ParamValue) + values + (@RequestId,@Param4,@Param4Value); + + if @Param5 collate Latin1_General_100_BIN2 is not null and + @Param5Value collate Latin1_General_100_BIN2 is not null + insert into dbo.WebRequestParams_Memory + (RequestID,ParamName,ParamValue) + values + (@RequestId,@Param5,@Param5Value); + end + end + end + end +end +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/02.Chapter 02 (In-Memory OLTP Objects)/02.Chapter 02 (In-Memory OLTP Objects).ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/02.Chapter 02 (In-Memory OLTP Objects)/02.Chapter 02 (In-Memory OLTP Objects).ssmssqlproj new file mode 100644 index 0000000..a65ff59 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/02.Chapter 02 (In-Memory OLTP Objects)/02.Chapter 02 (In-Memory OLTP Objects).ssmssqlproj @@ -0,0 +1,27 @@ + + + + + + + + + + + + + 01.Creating Memory-Optimized Objects.sql + + + + + + 02.Creating On-Disk Objects.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/02.Chapter 02 (In-Memory OLTP Objects)/02.Creating On-Disk Objects.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/02.Chapter 02 (In-Memory OLTP Objects)/02.Creating On-Disk Objects.sql new file mode 100644 index 0000000..6b6c7ce --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/02.Chapter 02 (In-Memory OLTP Objects)/02.Creating On-Disk Objects.sql @@ -0,0 +1,150 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 02: In-Memory OLTP Objects */ +/* 02.Creating On-Disk Objects */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/****************************************************************************/ +/* Scripts in this chapter prepare the database schema for */ +/* LogRequestsGenerator demo app */ +/****************************************************************************/ + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertRequestInfo_Disk' and s.name = 'dbo') drop proc dbo.InsertRequestInfo_Disk; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'WebRequests_Disk' and s.name = 'dbo') drop table dbo.WebRequests_Disk; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'WebRequestHeaders_Disk' and s.name = 'dbo') drop table dbo.WebRequestHeaders_Disk; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'WebRequestParams_Disk' and s.name = 'dbo') drop table dbo.WebRequestParams_Disk; +go + +create table dbo.WebRequests_Disk +( + RequestId int not null identity(1,1), + RequestTime datetime2(4) not null + constraint DEF_WebRequests_Disk_RequestTime + default sysutcdatetime(), + URL varchar(255) not null, + RequestType tinyint not null, -- GET/POST/PUT + ClientIP varchar(15) not null, + BytesReceived int not null, + + constraint PK_WebRequests_Disk + primary key nonclustered(RequestID) + on [LOGDATA] +) on [LOGDATA] +go + +create unique clustered index IDX_WebRequests_Disk_RequestTime_RequestId +on dbo.WebRequests_Disk(RequestTime,RequestId) +on [LOGDATA] +go + +/* Foreign Keys have not been defined to make on-disk and memory-optimized tables +as similar as possible */ +create table dbo.WebRequestHeaders_Disk +( + RequestId int not null, + HeaderName varchar(64) not null, + HeaderValue varchar(256) not null, + + constraint PK_WebRequestHeaders_Disk + primary key clustered(RequestID,HeaderName) + on [LOGDATA] +) +go + +create table dbo.WebRequestParams_Disk +( + RequestId int not null, + ParamName varchar(64) not null, + ParamValue nvarchar(256) not null, + + constraint PK_WebRequestParams_Disk + primary key clustered(RequestID,ParamName) + on [LOGDATA] +) +go + +create proc dbo.InsertRequestInfo_Disk +( + @URL varchar(255) + ,@RequestType tinyint + ,@ClientIP varchar(15) + ,@BytesReceived int + -- Header fields + ,@Authorization varchar(256) + ,@UserAgent varchar(256) + ,@Host varchar(256) + ,@Connection varchar(256) + ,@Referer varchar(256) + -- Parameters.. Just for the demo purposes + ,@Param1 varchar(64) = null + ,@Param1Value nvarchar(256) = null + ,@Param2 varchar(64) = null + ,@Param2Value nvarchar(256) = null + ,@Param3 varchar(64) = null + ,@Param3Value nvarchar(256) = null + ,@Param4 varchar(64) = null + ,@Param4Value nvarchar(256) = null + ,@Param5 varchar(64) = null + ,@Param5Value nvarchar(256) = null +) +as +begin + set nocount on + set xact_abort on + + declare + @RequestId int + + begin tran + insert into dbo.WebRequests_Disk + (URL,RequestType,ClientIP,BytesReceived) + values + (@URL,@RequestType,@ClientIP,@BytesReceived); + + select @RequestId = SCOPE_IDENTITY(); + + insert into dbo.WebRequestHeaders_Disk + (RequestId,HeaderName,HeaderValue) + values + (@RequestId,'AUTHORIZATION',@Authorization) + ,(@RequestId,'USERAGENT',@UserAgent) + ,(@RequestId,'HOST',@Host) + ,(@RequestId,'CONNECTION',@Connection) + ,(@RequestId,'REFERER',@Referer); + + ;with Params(ParamName, ParamValue) + as + ( + select ParamName, ParamValue + from ( + values + (@Param1, @Param1Value) + ,(@Param2, @Param2Value) + ,(@Param3, @Param3Value) + ,(@Param4, @Param4Value) + ,(@Param5, @Param5Value) + ) v(ParamName, ParamValue) + where + ParamName is not null and + ParamValue is not null + ) + insert into dbo.WebRequestParams_Disk + (RequestID,ParamName,ParamValue) + select @RequestId, ParamName, ParamValue + from Params; + commit +end +go + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/01.Bucket_Count and Performance.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/01.Bucket_Count and Performance.sql new file mode 100644 index 0000000..860e5d6 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/01.Bucket_Count and Performance.sql @@ -0,0 +1,113 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 04: Hash Indexes */ +/* 01.Bucket_Count and Performance */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'HashIndex_LowBucketCount' and s.name = 'dbo') drop table dbo.HashIndex_LowBucketCount; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'HashIndex_HighBucketCount' and s.name = 'dbo') drop table dbo.HashIndex_HighBucketCount; + +create table dbo.HashIndex_LowBucketCount +( + Id int not null + constraint PK_HashIndex_LowBucketCount + primary key nonclustered + hash with (bucket_count=1000), + Value int not null +) +with (memory_optimized=on, durability=schema_only); + +create table dbo.HashIndex_HighBucketCount +( + Id int not null + constraint PK_HashIndex_HighBucketCount + primary key nonclustered + hash with (bucket_count=1000000), + Value int not null +) +with (memory_optimized=on, durability=schema_only); +go + +/* Insert Performance */ +set statistics time on +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N4 as t2) -- 65,536 rows +,N6(C) as (select 0 from N5 as t1 cross join N3 as t2) -- 1,048,576 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N6) +insert into dbo.HashIndex_HighBucketCount(Id, Value) + select Id, Id + from ids + where Id <= 1000000; + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N4 as t2) -- 65,536 rows +,N6(C) as (select 0 from N5 as t1 cross join N3 as t2) -- 1,048,576 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N6) +insert into dbo.HashIndex_LowBucketCount(Id, Value) + select Id, Id + from ids + where Id <= 1000000; +set statistics time off +go + +/* Select Performance */ +declare + @T table(Id int not null primary key) + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N4 as t2) -- 65,536 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N5) +insert into @T(Id) + select Id from Ids; + +set statistics time on +select t.id, c.Cnt +from @T t + cross apply + ( + select count(*) as Cnt + from dbo.HashIndex_HighBucketCount h + where h.Id = t.Id + ) c; + +select t.id, c.Cnt +from @T t + cross apply + ( + select count(*) as Cnt + from dbo.HashIndex_LowBucketCount h + where h.Id = t.Id + ) c; + +set statistics time off; +go + +/* Scan Performance */ +set statistics time on; + +select count(*) from dbo.HashIndex_HighBucketCount; +select count(*) from dbo.HashIndex_LowBucketCount; + +set statistics time off; +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/02.Hash Indexes Info.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/02.Hash Indexes Info.sql new file mode 100644 index 0000000..b32fb0c --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/02.Hash Indexes Info.sql @@ -0,0 +1,37 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 04: Hash Indexes */ +/* 02.Obtaining Information about Hash Indexes */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +select + s.name + '.' + t.name as [Table] + ,i.name as [Index] + ,stat.total_bucket_count as [Total Buckets] + ,stat.empty_bucket_count as [Empty Buckets] + ,floor(100. * empty_bucket_count / total_bucket_count) + as [Empty Bucket %] + ,stat.avg_chain_length as [Avg Chain] + ,stat.max_chain_length as [Max Chain] +from + sys.dm_db_xtp_hash_index_stats stat + join sys.tables t on + stat.object_id = t.object_id + join sys.indexes i on + stat.object_id = i.object_id and + stat.index_id = i.index_id + join sys.schemas s on + t.schema_id = s.schema_id; +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/03.Sargability.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/03.Sargability.sql new file mode 100644 index 0000000..36c0ccc --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/03.Sargability.sql @@ -0,0 +1,112 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 04: Hash Indexes */ +/* 03.Hash Indexes and SARGability */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'CustomersOnDisk' and s.name = 'dbo') drop table dbo.CustomersOnDisk; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'CustomersMemoryOptimized' and s.name = 'dbo') drop table dbo.CustomersMemoryOptimized; + +create table dbo.CustomersOnDisk +( + CustomerId int not null identity(1,1), + FirstName varchar(64) collate Latin1_General_100_BIN2 not null, + LastName varchar(64) collate Latin1_General_100_BIN2 not null, + Placeholder char(100) null, + + constraint PK_CustomersOnDisk + primary key clustered(CustomerId) +); + +create nonclustered index IDX_CustomersOnDisk_LastName_FirstName +on dbo.CustomersOnDisk(LastName, FirstName) +go + +create table dbo.CustomersMemoryOptimized +( + CustomerId int not null identity(1,1) + constraint PK_CustomersMemoryOptimized + primary key nonclustered + hash with (bucket_count = 30000), + FirstName varchar(64) collate Latin1_General_100_BIN2 not null, + LastName varchar(64) collate Latin1_General_100_BIN2 not null, + Placeholder char(100) null, + + index IDX_CustomersMemoryOptimized_LastName_FirstName + nonclustered hash(LastName, FirstName) + with (bucket_count = 1024), +) +with (memory_optimized = on, durability = schema_only) +go + +-- Inserting cross-joined data for all first and last names 50 times +-- using GO 50 command in Management Studio +;with FirstNames(FirstName) +as +( + select Names.Name + from + ( + values('Andrew'),('Andy'),('Anton'),('Ashley'),('Boris'), + ('Brian'),('Cristopher'),('Cathy'),('Daniel'),('Donny'), + ('Edward'),('Eddy'),('Emy'),('Frank'),('George'),('Harry'), + ('Henry'),('Ida'),('John'),('Jimmy'),('Jenny'),('Jack'), + ('Kathy'),('Kim'),('Larry'),('Mary'),('Max'),('Nancy'), + ('Olivia'),('Paul'),('Peter'),('Patrick'),('Robert'), + ('Ron'),('Steve'),('Shawn'),('Tom'),('Timothy'), + ('Uri'),('Vincent') + ) Names(Name) +) +,LastNames(LastName) +as +( + select Names.Name + from + ( + values('Smith'),('Johnson'),('Williams'),('Jones'),('Brown'), + ('Davis'),('Miller'),('Wilson'),('Moore'),('Taylor'), + ('Anderson'),('Jackson'),('White'),('Harris') + ) Names(Name) +) +insert into dbo.CustomersOnDisk(LastName, FirstName) + select LastName, FirstName + from FirstNames cross join LastNames +go 50 + +insert into dbo.CustomersMemoryOptimized(LastName, FirstName) + select LastName, FirstName + from dbo.CustomersOnDisk; +go + +/* Check Execution Plans */ +select CustomerId, FirstName, LastName +from dbo.CustomersOnDisk +where FirstName = 'Paul' and LastName = 'White'; + +select CustomerId, FirstName, LastName +from dbo.CustomersMemoryOptimized +where FirstName = 'Paul' and LastName = 'White'; +go + +select CustomerId, FirstName, LastName +from dbo.CustomersOnDisk +where LastName = 'White'; + +select CustomerId, FirstName, LastName +from dbo.CustomersMemoryOptimized +where LastName = 'White'; +go + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/04.Chapter 04 (Hash Indexes).ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/04.Chapter 04 (Hash Indexes).ssmssqlproj new file mode 100644 index 0000000..eb575b9 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/04.Chapter 04 (Hash Indexes).ssmssqlproj @@ -0,0 +1,45 @@ + + + + + + + + + + + + + 01.Bucket_Count and Performance.sql + + + + + + 02.Hash Indexes Info.sql + + + + + + 03.Sargability.sql + + + + + + 04.Statistics.sql + + + + + + 05.Bad Exec Plans.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/04.Statistics.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/04.Statistics.sql new file mode 100644 index 0000000..0710fe0 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/04.Statistics.sql @@ -0,0 +1,35 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 04: Hash Indexes */ +/* 04.Statistics */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +dbcc show_statistics +( + 'dbo.HashIndex_HighBucketCount' + ,'PK_HashIndex_HighBucketCount' +) +go + +update statistics dbo.HashIndex_HighBucketCount +with fullscan, norecompute; +go + +dbcc show_statistics +( + 'dbo.HashIndex_HighBucketCount' + ,'PK_HashIndex_HighBucketCount' +) +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/05.Bad Exec Plans.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/05.Bad Exec Plans.sql new file mode 100644 index 0000000..6d5a671 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/04.Chapter 04 (Hash Indexes)/05.Bad Exec Plans.sql @@ -0,0 +1,129 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 04: Hash Indexes */ +/* 05.Bad Execution Plans due to Missing Statistics */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'T1' and s.name = 'dbo') drop table dbo.T1; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'T2' and s.name = 'dbo') drop table dbo.T2; +go + +create table dbo.T1 +( + ID int not null identity(1,1) + primary key nonclustered hash + with (bucket_count = 8192), + T1Col int not null, + Placeholder char(100) not null + constraint DEF_T1_Placeholder + default('1'), + + index IDX_T1Col + nonclustered hash(T1Col) + with (bucket_count = 1024) +) +with (memory_optimized = on, durability = schema_only); + +create table dbo.T2 +( + ID int not null identity(1,1) + primary key nonclustered hash + with (bucket_count = 8192), + T2Col int not null, + Placeholder char(100) not null + constraint DEF_T2_Placeholder + default('2'), + + index IDX_T2Col + nonclustered hash(T2Col) + with (bucket_count = 1024) +) +with (memory_optimized = on, durability = schema_only); +go + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N3 as t2) -- 4,096 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N5) +insert into dbo.T1(T1Col) + select 1 from Ids; + +insert into dbo.T2(T2Col) + select -1 from dbo.T1; + +update dbo.T1 +set T1Col = 2 +where ID = 4096; + +update dbo.T2 +set T2Col = -2 +where ID = 1; +go + +/* Data Distribution in the Tables */ +select 'T1' as [Table], T1Col as [Value], count(*) as [Count] +from dbo.T1 +group by T1Col + +union all + +select 'T2' as [Table], T2Col as [Value], count(*) as [Count] +from dbo.T2 +group by T2Col; + +/* Check Execution Plans */ +select * +from dbo.T1 t1 join dbo.T2 t2 on + t1.ID = t2.ID +where + t1.T1Col = 2 and + t2.T2Col = -1; + +select * +from dbo.T1 t1 join dbo.T2 t2 on + t1.ID = t2.ID +where + t1.T1Col = 1 and + t2.T2Col = -2; +go + +/* Update Statistics */ +update statistics dbo.T1 with fullscan, norecompute; +update statistics dbo.T2 with fullscan, norecompute; + +dbcc show_statistics('dbo.T1','IDX_T1Col'); +dbcc show_statistics('dbo.T2','IDX_T2Col'); +go + +/* Check Execution Plans */ +select * +from dbo.T1 t1 join dbo.T2 t2 on + t1.ID = t2.ID +where + t1.T1Col = 2 and + t2.T2Col = -1; + +select * +from dbo.T1 t1 join dbo.T2 t2 on + t1.ID = t2.ID +where + t1.T1Col = 1 and + t2.T2Col = -2; +go + + + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/01.Sargability.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/01.Sargability.sql new file mode 100644 index 0000000..a938590 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/01.Sargability.sql @@ -0,0 +1,160 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 05: Nonclustered Indexes */ +/* 01.SARGability */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Customers_OnDisk' and s.name = 'dbo') drop table dbo.Customers_OnDisk; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Customers' and s.name = 'dbo') drop table dbo.Customers; +go + +create table dbo.Customers +( + CustomerId int identity(1,1) not null + constraint PK_Customers + primary key nonclustered + hash with (bucket_count=1000), + FirstName varchar(32) + collate Latin1_General_100_BIN2 not null, + LastName varchar(64) + collate Latin1_General_100_BIN2 not null, + FullName varchar(97) + collate Latin1_General_100_BIN2 not null, + + index IDX_LastName_FirstName + nonclustered(LastName, FirstName), + + index IDX_FullName + nonclustered(FullName) +) +with (memory_optimized=on, durability=schema_only); + +create table dbo.Customers_OnDisk +( + CustomerId int identity(1,1) not null, + FirstName varchar(32) not null, + LastName varchar(64) not null, + FullName varchar(97) not null, + + constraint PK_Customers_OnDisk + primary key clustered(CustomerId) +); + +create nonclustered index IDX_Customers_OnDisk_LastName_FirstName +on dbo.Customers_OnDisk(LastName, FirstName); + +create nonclustered index IDX_Customers_OnDisk_FullName +on dbo.Customers_OnDisk(FullName); +go + +;with FirstNames(FirstName) +as +( + select Names.Name + from + ( + values('Andrew'),('Andy'),('Anton'),('Ashley'),('Boris'), + ('Brian'),('Cristopher'),('Cathy'),('Daniel'),('DONALD'), + ('Edward'),('Eddy'),('Emy'),('Frank'),('George'),('Harry'), + ('Henry'),('Ida'),('John'),('Jimmy'),('Jenny'),('Jack'), + ('Kathy'),('Kim'),('Larry'),('Mary'),('Max'),('Nancy'), + ('Olivia'),('Paul'),('Peter'),('Patrick'),('Robert'), + ('Ron'),('Steve'),('Shawn'),('Tom'),('Timothy'), + ('Uri'),('Vincent') + ) Names(Name) +) +,LastNames(LastName) +as +( + select Names.Name + from + ( + values('Smith'),('Johnson'),('Williams'),('Jones'),('Brown'), + ('Davis'),('Miller'),('Wilson'),('Moore'),('Taylor'), + ('Anderson'),('Jackson'),('White'),('Harris') + ) Names(Name) +) +insert into dbo.Customers(LastName, FirstName, FullName) + select LastName, FirstName, FirstName + ' ' + LastName + from FirstNames cross join LastNames; + +insert into dbo.Customers_OnDisk(LastName, FirstName, FullName) + select LastName, FirstName, FullName + from dbo.Customers; +go + +/* Check Execution Plans */ + +/* SARGable Predicates */ +-- Point-Lookup specifying all columns in the index +select CustomerId, FirstName, LastName +from dbo.Customers +where LastName = 'White' and FirstName = 'Paul'; + +-- Point-lookup using leftmost index column +select CustomerId, FirstName, LastName +from dbo.Customers +where LastName = 'White'; + +-- Using ">", ">=", "<", "<=" comparison +select CustomerId, FirstName, LastName +from dbo.Customers +where LastName > 'White'; + +-- Prefix Search +select CustomerId, FirstName, LastName +from dbo.Customers +where LastName like 'Wh%'; + +-- IN list +select CustomerId, FirstName, LastName +from dbo.Customers +where LastName in ('White','Moore'); + + +/* Non-SARGable Predicates */ +-- Omitting left-most index column(s) +select CustomerId, FirstName, LastName +from dbo.Customers +where FirstName = 'Paul'; + +-- Substring Search +select CustomerId, FirstName, LastName +from dbo.Customers +where LastName like '%hit%'; + +-- Functions +select CustomerId, FirstName, LastName +from dbo.Customers +where len(LastName) = 5; + +/* Sorting in the direction of the index key */ +select top 3 CustomerId, FirstName, LastName, FullName +from dbo.Customers_OnDisk +order by FullName ASC; + +select top 3 CustomerId, FirstName, LastName, FullName +from dbo.Customers +order by FullName ASC; + +/* Sorting in the direction opposite to the index key */ +select top 3 CustomerId, FirstName, LastName, FullName +from dbo.Customers_OnDisk +order by FullName DESC; + +select top 3 CustomerId, FirstName, LastName, FullName +from dbo.Customers +order by FullName DESC; diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/02.DMVs.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/02.DMVs.sql new file mode 100644 index 0000000..238a5c0 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/02.DMVs.sql @@ -0,0 +1,60 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 05: Nonclustered Indexes */ +/* 02.Obtaining Information about Nonclustered Indexes */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +select + s.name + '.' + t.name as [table] + ,i.index_id + ,i.name as [index] + ,i.type_desc as [type] + ,st.scans_started + ,st.rows_returned + ,iif(st.scans_started = 0, 0, + floor(st.rows_returned / st.scans_started)) as [rows per scan] +from + sys.dm_db_xtp_index_stats st join sys.tables t on + st.object_id = t.object_id + join sys.indexes i on + st.object_id = i.object_id and + st.index_id = i.index_id + join sys.schemas s on + s.schema_id = t.schema_id +where + s.name = 'dbo' and t.name = 'Customers'; + +select + s.name + '.' + t.name as [table] + ,i.index_id + ,i.name as [index] + ,i.type_desc as [type] + ,st.delta_pages + ,st.leaf_pages + ,st.internal_pages + ,st.leaf_pages + st.delta_pages + st.internal_pages + as [total pages] +from + sys.dm_db_xtp_nonclustered_index_stats st + join sys.tables t on + st.object_id = t.object_id + join sys.indexes i on + st.object_id = i.object_id and + st.index_id = i.index_id + join sys.schemas s on + s.schema_id = t.schema_id +where + s.name = 'dbo' and t.name = 'Customers'; + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/03.Hash vs Nonclustered.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/03.Hash vs Nonclustered.sql new file mode 100644 index 0000000..7dc85ca --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/03.Hash vs Nonclustered.sql @@ -0,0 +1,154 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 05: Nonclustered Indexes */ +/* 03.Hash vs. Nonclustered Indexes */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Hash_131072' and s.name = 'dbo') drop table dbo.Hash_131072; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Hash_16384' and s.name = 'dbo') drop table dbo.Hash_16384; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Hash_1024' and s.name = 'dbo') drop table dbo.Hash_1024; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'NonClusteredIdx' and s.name = 'dbo') drop table dbo.NonClusteredIdx; +go + +create table dbo.Hash_131072 +( + Id int not null + constraint PK_Hash_131072 + primary key nonclustered + hash with (bucket_count=131072), + Value int not null, + + index IDX_Value hash(Value) + with (bucket_count=131072) +) +with (memory_optimized=on, durability=schema_only); + +create table dbo.Hash_16384 +( + Id int not null + constraint PK_Hash_16384 + primary key nonclustered + hash with (bucket_count=16384), + Value int not null, + + index IDX_Value hash(Value) + with (bucket_count=16384) +) +with (memory_optimized=on, durability=schema_only); + +create table dbo.Hash_1024 +( + Id int not null + constraint PK_Hash_1014 + primary key nonclustered + hash with (bucket_count=1024), + Value int not null, + + index IDX_Value hash(Value) + with (bucket_count=1024) +) +with (memory_optimized=on, durability=schema_only); + +create table dbo.NonClusteredIdx +( + Id int not null + constraint PK_NonClusteredIdx + primary key nonclustered + hash with (bucket_count=131072), + Value int not null, + + index IDX_Value nonclustered(Value) +) +with (memory_optimized=on, durability=schema_only); +go + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N4 as t2) -- 65,536 rows +,N6(C) as (select 0 from N5 as t1 cross join N1 as t2) -- 131,072 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N6) +insert into dbo.Hash_131072(Id,Value) + select Id, Id + from ids + where Id <= 75000; + +insert into dbo.Hash_16384(Id,Value) + select Id, Value + from dbo.Hash_131072; + +insert into dbo.Hash_1024(Id,Value) + select Id, Value + from dbo.Hash_131072; + +insert into dbo.NonClusteredIdx(Id,Value) + select Id, Value + from dbo.Hash_131072; +go + +declare + @T table(Value int not null primary key) + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N4 as t2) -- 65,536 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N5) +insert into @T(Value) + select Id from Ids; + +set statistics time on + +select t.Value, c.Cnt +from @T t + cross apply + ( + select count(*) as Cnt + from dbo.Hash_131072 h + where h.Value = t.Value + ) c; + +select t.Value, c.Cnt +from @T t + cross apply + ( + select count(*) as Cnt + from dbo.Hash_16384 h + where h.Value = t.Value + ) c; + +select t.Value, c.Cnt +from @T t + cross apply + ( + select count(*) as Cnt + from dbo.Hash_1024 h + where h.Value = t.Value + ) c; + +select t.Value, c.Cnt +from @T t + cross apply + ( + select count(*) as Cnt + from dbo.NonClusteredIdx h + where h.Value = t.Value + ) c; + +set statistics time off +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/05.Chapter 05 (Nonclustered Indexes).ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/05.Chapter 05 (Nonclustered Indexes).ssmssqlproj new file mode 100644 index 0000000..a179459 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/05.Chapter 05 (Nonclustered Indexes)/05.Chapter 05 (Nonclustered Indexes).ssmssqlproj @@ -0,0 +1,33 @@ + + + + + + + + + + + + + 01.Sargability.sql + + + + + + 02.DMVs.sql + + + + + + 03.Hash vs Nonclustered.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/01.Natively Compiled Objects.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/01.Natively Compiled Objects.sql new file mode 100644 index 0000000..fed8d97 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/01.Natively Compiled Objects.sql @@ -0,0 +1,37 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 06: In-Memory OLTP Programmability */ +/* 01.Natively Compiled Objects */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +select + s.name + '.' + o.name as [Object Name] + ,o.object_id +from + ( + select schema_id, name, object_id + from sys.tables + where is_memory_optimized = 1 + + union all + + select schema_id, name, object_id + from sys.procedures + ) o join sys.schemas s on + o.schema_id = s.schema_id; + +select base_address, file_version, language, description, name +from sys.dm_os_loaded_modules +where description = 'XTP Native DLL'; diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/02.1.Atomic Blocks.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/02.1.Atomic Blocks.sql new file mode 100644 index 0000000..4c47ef1 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/02.1.Atomic Blocks.sql @@ -0,0 +1,77 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 06: In-Memory OLTP Programmability */ +/* 02.Atomic Blocks (Session 1) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'AtomicBlockDemo' and s.name = 'dbo') drop proc dbo.AtomicBlockDemo; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'MOData' and s.name = 'dbo') drop table dbo.MOData; + +create table dbo.MOData +( + ID int not null + primary key nonclustered + hash with (bucket_count=10), + Value int null +) +with (memory_optimized=on, durability=schema_only); + +insert into dbo.MOData(ID, Value) +values + (1,1), (2,2) +go + +create proc dbo.AtomicBlockDemo +( + @ID1 int not null + ,@Value1 bigint not null + ,@ID2 int + ,@Value2 bigint +) +with native_compilation, schemabinding, execute as owner +as +begin atomic +with (transaction isolation level = snapshot, language=N'us_english') + update dbo.MOData set Value = @Value1 where ID = @ID1 + if @ID2 is not null + update dbo.MOData set Value = @Value2 where ID = @ID2 +end +go + +/*** Non-Critical Errors ***/ +-- Step 1 +begin tran + exec dbo.AtomicBlockDemo 1, -1, 2, -2 + exec dbo.AtomicBlockDemo 1, 0, 2, 999999999999999 + + -- Step 2 + select @@TRANCOUNT as [@@TRANCOUNT], XACT_STATE() as [XACT_STATE()] +commit +go +select * from dbo.MOData +go + +/*** Critical Errors ***/ +-- Step 1 +begin tran + exec dbo.AtomicBlockDemo 1, 0, null, null + + /*** Run Session 2 code to trigger write/write conflict ***/ + -- Step 2 + select @@TRANCOUNT as [@@TRANCOUNT], XACT_STATE() as [XACT_STATE()] +commit +go +select * from dbo.MOData +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/02.2.Atomic Blocks.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/02.2.Atomic Blocks.sql new file mode 100644 index 0000000..28edaa6 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/02.2.Atomic Blocks.sql @@ -0,0 +1,24 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 06: In-Memory OLTP Programmability */ +/* 02.Atomic Blocks (Session 2) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +/*** Critical Errors ***/ +-- Run together with Session 1 code +begin tran + exec dbo.AtomicBlockDemo 1, 0, null, null + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/03.Perf Comparison.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/03.Perf Comparison.sql new file mode 100644 index 0000000..6bbb291 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/03.Perf Comparison.sql @@ -0,0 +1,340 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 06: In-Memory OLTP Programmability */ +/* 03.Performance Comparison */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertCustomers_Row' and s.name = 'dbo') drop proc dbo.InsertCustomers_Row; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertCustomers_Batch' and s.name = 'dbo') drop proc dbo.InsertCustomers_Batch; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertCustomers_NativelyCompiled' and s.name = 'dbo') drop proc dbo.InsertCustomers_NativelyCompiled; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'UpdateCustomers' and s.name = 'dbo') drop proc dbo.UpdateCustomers; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertOrders' and s.name = 'dbo') drop proc dbo.InsertOrders; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'GetTopCustomers' and s.name = 'dbo') drop proc dbo.GetTopCustomers; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'DeleteCustomersAndOrders' and s.name = 'dbo') drop proc dbo.DeleteCustomersAndOrders; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Customers' and s.name = 'dbo') drop table dbo.Customers; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Orders' and s.name = 'dbo') drop table dbo.Orders; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Numbers' and s.name = 'dbo') drop table dbo.Numbers; +go + +create table dbo.Customers +( + CustomerId int not null + primary key nonclustered + hash with (bucket_count=200000), + Name nvarchar(255) + collate Latin1_General_100_BIN2 not null, + CreatedOn datetime2(0) not null + constraint DEF_Customers_CreatedOn + default sysutcdatetime(), + Placeholder char(200) not null, + + index IDX_Name nonclustered(Name) +) +with (memory_optimized=on, durability=schema_only); + +create table dbo.Orders +( + OrderId int not null + primary key nonclustered + hash with (bucket_count=5000000), + CustomerId int not null, + OrderNum varchar(32) + collate Latin1_General_100_BIN2 not null, + OrderDate datetime2(0) not null + constraint DEF_Orders_OrderDate + default sysutcdatetime(), + Amount money not null, + Placeholder char(200) not null, + + index IDX_CustomerId + nonclustered hash(CustomerId) + with (bucket_count=200000), + + index IDX_OrderNum nonclustered(OrderNum) +) +with (memory_optimized=on, durability=schema_only); + +create table dbo.Numbers +( + Num int not null + constraint PK_Numbers + primary key clustered +); +go + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N4 as t2) -- 65,536 rows +,N6(C) as (select 0 from N5 as t1 cross join N3 as t2) -- 1,048,576 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N6) +insert into dbo.Numbers(Num) + select Id from Ids; +go +create proc dbo.InsertCustomers_Row +( + @NumCustomers int +) +as +begin + set nocount on + set xact_abort on + + declare + @I int = 1; + + begin tran + while @I <= @NumCustomers + begin + insert into dbo.Customers(CustomerId,Name,Placeholder) + values(@I,N'Customer ' + convert(nvarchar(10),@I), 'Some data'); + + set @I += 1; + end; + commit +end +go + +create proc dbo.InsertCustomers_Batch +( + @NumCustomers int +) +as +begin + set nocount on + set xact_abort on + + if @NumCustomers > 1048576 + begin + raiserror('@NumCustomers should not exceed 1,048,576',10,1); + return; + end; + + begin tran + insert into dbo.Customers(CustomerId,Name,Placeholder) + select Num, N'Customer ' + convert(nvarchar(10),Num), 'Some data' + from dbo.Numbers + where Num <= @NumCustomers + commit +end +go + +create proc dbo.InsertCustomers_NativelyCompiled +( + @NumCustomers int not null +) +with native_compilation, schemabinding, execute as owner +as +begin atomic with +( + transaction isolation level = snapshot + ,language = N'English' +) + declare + @I int = 1; + + while @I <= @NumCustomers + begin + insert into dbo.Customers(CustomerId,Name,Placeholder) + values(@I,N'Customer ' + convert(nvarchar(10),@I), 'Some data'); + + set @I += 1; + end; +end +go + +/* Testing Insert Performance */ +-- InsertCustomers_Row +delete from dbo.Customers; +declare + @DT datetime = getDate(); +exec dbo.InsertCustomers_Row @NumCustomers = 10000; +select datediff(millisecond,@DT, GetDate()) as [Row 10K]; + +delete from dbo.Customers; +select @DT = getdate(); +exec dbo.InsertCustomers_Row @NumCustomers = 50000; +select datediff(millisecond,@DT, GetDate()) as [Row 50K]; + +delete from dbo.Customers; +select @DT = getdate(); +exec dbo.InsertCustomers_Row @NumCustomers = 100000; +select datediff(millisecond,@DT, GetDate()) as [Row 100K]; +go + + +-- InsertCustomers_Batch +delete from dbo.Customers; +declare + @DT datetime = getDate(); +exec dbo.InsertCustomers_Batch @NumCustomers = 10000; +select datediff(millisecond,@DT, GetDate()) as [Batch 10K]; + +delete from dbo.Customers; +select @DT = getdate(); +exec dbo.InsertCustomers_Batch @NumCustomers = 50000; +select datediff(millisecond,@DT, GetDate()) as [Batch 50K]; + +delete from dbo.Customers; +select @DT = getdate(); +exec dbo.InsertCustomers_Batch @NumCustomers = 100000; +select datediff(millisecond,@DT, GetDate()) as [Batch 100K]; +go + +-- InsertCustomers_NativelyCompiled +delete from dbo.Customers; +declare + @DT datetime = getDate(); +exec dbo.InsertCustomers_NativelyCompiled 10000; +select datediff(millisecond,@DT, GetDate()) as [Natively Compileda 10K]; + +delete from dbo.Customers; +select @DT = getdate(); +exec dbo.InsertCustomers_NativelyCompiled 50000; +select datediff(millisecond,@DT, GetDate()) as [Natively Compileda 50K]; + +delete from dbo.Customers; +select @DT = getdate(); +exec dbo.InsertCustomers_NativelyCompiled 100000; +select datediff(millisecond,@DT, GetDate()) as [Natively Compileda 100K]; +go + +create proc dbo.UpdateCustomers +( + @Placeholder char(100) not null +) +with native_compilation, schemabinding, execute as owner +as +begin atomic with +( + transaction isolation level = snapshot + ,language = N'English' +) + update dbo.Customers + set Placeholder = @Placeholder + where CustomerId % 2 = 0; +end +go + +/* Testing updates */ +declare + @DT datetime = getDate(); +exec dbo.UpdateCustomers 'Using Natively Compiled SP'; +select datediff(millisecond,@DT, GetDate()) as [Update Natively Compiled]; + +select @DT = getdate(); +update dbo.Customers +set Placeholder = 'Using interop engine' +where CustomerId % 2 = 1; +select datediff(millisecond,@DT, GetDate()) as [Update Interop] +go + +/* Populating Orders table */ +insert into dbo.Orders(OrderId, CustomerId, OrderNum, Amount,Placeholder) + select + Num + ,Num % 100000 + 1 + ,'Order ' + convert(nvarchar(10),Num) + ,Num / 100. + ,'Some data' + from Numbers + where Num <= 1000000 +go + +/* Select Performance */ +create proc dbo.GetTopCustomers +with native_compilation, schemabinding, execute as owner +as +begin atomic with +( + transaction isolation level = snapshot + ,language = N'English' +) + select top 10 + c.CustomerId, c.Name, count(o.OrderId) as [Order Cnt] + ,max(o.OrderDate) as [Most Recent Order Date] + ,sum(o.Amount) as [Total Amount] + from + dbo.Customers c join dbo.Orders o on + c.CustomerId = o.CustomerId + group by + c.CustomerId, c.Name + order by + sum(o.Amount) desc; +end +go + +declare + @DT datetime = getDate(); +exec dbo.GetTopCustomers +select datediff(millisecond,@DT, GetDate()) as [GetTopCustomers] + +select @DT = getdate(); + select top 10 + c.CustomerId, c.Name, count(o.OrderId) as [Order Cnt] + ,max(o.OrderDate) as [Most Recent Order Date] + ,sum(o.Amount) as [Total Amount] + from + dbo.Customers c join dbo.Orders o on + c.CustomerId = o.CustomerId + group by + c.CustomerId, c.Name + order by + sum(o.Amount) desc; +select datediff(millisecond,@DT, GetDate()) as [Update Interop] +go + +/* Delete Performance */ + +create proc dbo.DeleteCustomersAndOrders +with native_compilation, schemabinding, execute as owner +as +begin atomic with +( + transaction isolation level = snapshot + ,language = N'English' +) + delete from dbo.Orders; + delete from dbo.Customers; +end +go + +declare + @DT datetime = getDate(); +exec dbo.DeleteCustomersAndOrders +select datediff(millisecond,@DT, GetDate()) as [DeleteCustomersAndOrders]; +go + +-- Repopulating the data +exec dbo.InsertCustomers_NativelyCompiled 100000; +insert into dbo.Orders(OrderId, CustomerId, OrderNum, Amount,Placeholder) + select + Num + ,Num % 100000 + 1 + ,'Order ' + convert(nvarchar(10),Num) + ,Num / 100. + ,'Some data' + from Numbers + where Num <= 1000000 +go + +declare + @DT datetime = getDate(); +select @DT = getdate(); + delete from dbo.Orders; + delete from dbo.Customers; +select datediff(millisecond,@DT, GetDate()) as [Delete Interop] +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/06.Chapter 06 (In-Memory OLTP Programmability).ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/06.Chapter 06 (In-Memory OLTP Programmability).ssmssqlproj new file mode 100644 index 0000000..b5dc729 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/06.Chapter 06 (In-Memory OLTP Programmability)/06.Chapter 06 (In-Memory OLTP Programmability).ssmssqlproj @@ -0,0 +1,39 @@ + + + + + + + + + + + + + 01.Natively Compiled Objects.sql + + + + + + 02.1.Atomic Blocks.sql + + + + + + 02.2.Atomic Blocks.sql + + + + + + 03.Perf Comparison.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/01.Table Creation.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/01.Table Creation.sql new file mode 100644 index 0000000..a12c0f6 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/01.Table Creation.sql @@ -0,0 +1,37 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 01.Table Creation */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'HKData' and s.name = 'dbo') drop table dbo.HKData; +go + +create table dbo.HKData +( + ID int not null, + Col int not null, + + constraint PK_HKData + primary key nonclustered hash(ID) + with (bucket_count=64), +) +with (memory_optimized=on, durability=schema_only) +go + +insert into dbo.HKData(ID, Col) +values(1,1),(2,2),(3,3),(4,4),(5,5); +go + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/02.1.Repeatable Read.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/02.1.Repeatable Read.sql new file mode 100644 index 0000000..abaa000 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/02.1.Repeatable Read.sql @@ -0,0 +1,45 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 02.REPEATABLE READ Isolation Level (Session 1) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/*** Test 1 ***/ +-- Step 1 +begin tran + select ID, Col + from dbo.HKData with (repeatableread) + + /*** Run Session 2 code ***/ + + -- Step 2 + select ID, Col + from dbo.HKData with (repeatableread) +commit +go + +/*** Test 2 ***/ +-- Step 1 +begin tran + select ID, Col + from dbo.HKData with (repeatableread) + + /*** Run Session 2 code ***/ + + -- Step 2 + select ID, Col + from dbo.HKData with (repeatableread) +commit +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/02.2.Repeatable Read.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/02.2.Repeatable Read.sql new file mode 100644 index 0000000..7d6a7ab --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/02.2.Repeatable Read.sql @@ -0,0 +1,28 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 02.REPEATABLE READ Isolation Level (Session 2) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/*** Test 1 ***/ +update dbo.HKData +set Col = -2 +where ID = 2 +go + +/*** Test 2 ***/ +insert into dbo.HKData +values(10,10) +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/03.1.Serializable.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/03.1.Serializable.sql new file mode 100644 index 0000000..66079ac --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/03.1.Serializable.sql @@ -0,0 +1,45 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 03.SERIALIZABLE Isolation Level (Session 1) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/*** Test 1 ***/ +-- Step 1 +begin tran + select ID, Col + from dbo.HKData with (serializable) + + /*** Run Session 2 code ***/ + + -- Step 2 + select ID, Col + from dbo.HKData with (serializable) +commit +go + +/*** Test 2 ***/ +-- Step 1 +begin tran + select ID, Col + from dbo.HKData with (serializable) + + /*** Run Session 2 code ***/ + + -- Step 2 + select ID, Col + from dbo.HKData with (serializable) +commit +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/03.2.Serializable.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/03.2.Serializable.sql new file mode 100644 index 0000000..4e559bb --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/03.2.Serializable.sql @@ -0,0 +1,28 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 03.SERIALIZABLE Isolation Level (Session 2) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/*** Test 1 ***/ +update dbo.HKData +set Col = -2 +where ID = 2 +go + +/*** Test 2 ***/ +insert into dbo.HKData +values(9,9) +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/04.1.Snapshot.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/04.1.Snapshot.sql new file mode 100644 index 0000000..a887343 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/04.1.Snapshot.sql @@ -0,0 +1,46 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 04.SNAPSHOT Isolation Level (Session 1) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +/*** Test 1 ***/ +-- Step 1 +begin tran + select ID, Col + from dbo.HKData with (Snapshot) + + /*** Run Session 2 code ***/ + + -- Step 2 + select ID, Col + from dbo.HKData with (Snapshot) +commit +go + +/*** Test 2 ***/ +-- Step 1 +begin tran + select ID, Col + from dbo.HKData with (Snapshot) + + /*** Run Session 2 code ***/ + + -- Step 2 + select ID, Col + from dbo.HKData with (Snapshot) +commit +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/04.2.Snapshot.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/04.2.Snapshot.sql new file mode 100644 index 0000000..df6a683 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/04.2.Snapshot.sql @@ -0,0 +1,28 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 04.SNAPSHOT Isolation Level (Session 2) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/*** Test 1 ***/ +update dbo.HKData +set Col = -20 +where ID = 2 +go + +/*** Test 2 ***/ +insert into dbo.HKData +values(8,8) +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/05.1.Write-Write Conflict.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/05.1.Write-Write Conflict.sql new file mode 100644 index 0000000..393c6cd --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/05.1.Write-Write Conflict.sql @@ -0,0 +1,51 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 05.Write/Write Conflict (Session 1) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + + +/*** Test 1 ***/ +-- Step 1 +begin tran + select ID, Col + from dbo.HKData with (snapshot) + + /*** Run Session 2 code ***/ + + -- Step 2 + update dbo.HKData with (snapshot) + set Col = -2 + where ID = 2 +commit +go + + + +/*** Test 2 ***/ +-- Step 1 +begin tran + select ID, Col + from dbo.HKData with (snapshot) + + /*** Run Session 2 code ***/ + + -- Step 2 + update dbo.HKData with (snapshot) + set Col = -2 + where ID = 2 +commit +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/05.2.Write-Write Conflict.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/05.2.Write-Write Conflict.sql new file mode 100644 index 0000000..e46b52f --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/05.2.Write-Write Conflict.sql @@ -0,0 +1,34 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 05.Write/Write Conflict (Session 2) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/*** Test 1 ***/ +begin tran + update dbo.HKData with (snapshot) + set Col = -2 + where ID = 2 +commit +go + +/*** Test 2 ***/ +begin tran + update dbo.HKData with (snapshot) + set Col = -2 + where ID = 2 + /*** Run Session 1: Step 2 Code ***/ +commit +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/06.1.PK Violation.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/06.1.PK Violation.sql new file mode 100644 index 0000000..563f7f0 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/06.1.PK Violation.sql @@ -0,0 +1,26 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 06.PK Violation (Snapshot Validation) (Session 1) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +-- STEP 1 +begin tran + insert into dbo.HKData with (snapshot) + (ID, Col) + values(100,100); + + /*** Run Session 2 code ***/ +commit diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/06.2.PK Violation.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/06.2.PK Violation.sql new file mode 100644 index 0000000..248339d --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/06.2.PK Violation.sql @@ -0,0 +1,25 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 07: In-Memory OLTP Concurrency Model */ +/* 06.PK Violation (Snapshot Validation) (Session 2) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +begin tran + insert into dbo.HKData with (snapshot) + (ID, Col) + values(100,100); + + /*** Commit Tran in Session 1 ***/ +commit diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/07.Chapter 07 (In-Memory OLTP Concurrency Model).ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/07.Chapter 07 (In-Memory OLTP Concurrency Model).ssmssqlproj new file mode 100644 index 0000000..69a3400 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/07.Chapter 07 (In-Memory OLTP Concurrency Model)/07.Chapter 07 (In-Memory OLTP Concurrency Model).ssmssqlproj @@ -0,0 +1,81 @@ + + + + + + + + + + + + + 01.Table Creation.sql + + + + + + 02.1.Repeatable Read.sql + + + + + + 02.2.Repeatable Read.sql + + + + + + 03.1.Serializable.sql + + + + + + 03.2.Serializable.sql + + + + + + 04.1.Snapshot.sql + + + + + + 04.2.Snapshot.sql + + + + + + 05.1.Write-Write Conflict.sql + + + + + + 05.2.Write-Write Conflict.sql + + + + + + 06.1.PK Violation.sql + + + + + + 06.2.PK Violation.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/08.Chapter 08 (Data Storage, Logging and Recovery)/01.Tran Logging.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/08.Chapter 08 (Data Storage, Logging and Recovery)/01.Tran Logging.sql new file mode 100644 index 0000000..f384c13 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/08.Chapter 08 (Data Storage, Logging and Recovery)/01.Tran Logging.sql @@ -0,0 +1,101 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 08: Data Storage, Logging and Recovery */ +/* 01.Transaction Logging */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'HKData' and s.name = 'dbo') drop table dbo.HKData; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'DiskData' and s.name = 'dbo') drop table dbo.DiskData; +go + +create table dbo.HKData +( + ID int not null, + Col int not null, + + constraint PK_HKData + primary key nonclustered hash(ID) + with (bucket_count=64), +) +with (memory_optimized=on, durability=schema_and_data) +go + +checkpoint +go + +/*** Creating Transaction Record ***/ +declare + @I int = 1 + +begin tran + while @I <= 50 + begin + insert into dbo.HKData with (snapshot) + (ID, Col) + values(@I, @I) + + set @I += 1 + end +commit +go + +/*** Analyzing Tran Log Content ***/ +select * +from sys.fn_dblog(NULL, NULL) +order by [Current LSN] desc; +go + + +/*** Analyzing Output of LOP_HK Record ***/ +select [Current LSN], object_name(table_id) as [Table] + ,operation_desc, tx_end_timestamp, total_size +from sys.fn_dblog_xtp(, + ) +go + +create table dbo.DiskData +( + ID int not null, + Col int not null, + + constraint PK_DiskData + primary key nonclustered(ID) +) +go + +checkpoint +go + +declare + @I int = 1 + +begin tran + while @I <= 500 + begin + insert into dbo.DiskData(ID, Col) + values(@I, @I) + + set @I += 1 + end +commit +go + +select * +from sys.fn_dblog(NULL, NULL) +order by [Current LSN] desc; +go + + + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/08.Chapter 08 (Data Storage, Logging and Recovery)/08.Chapter 08 (Data Storage, Logging and Recovery).ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/08.Chapter 08 (Data Storage, Logging and Recovery)/08.Chapter 08 (Data Storage, Logging and Recovery).ssmssqlproj new file mode 100644 index 0000000..4ecd1f4 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/08.Chapter 08 (Data Storage, Logging and Recovery)/08.Chapter 08 (Data Storage, Logging and Recovery).ssmssqlproj @@ -0,0 +1,21 @@ + + + + + + + + + + + + + 01.Tran Logging.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/01.Table Creation.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/01.Table Creation.sql new file mode 100644 index 0000000..4eeaee0 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/01.Table Creation.sql @@ -0,0 +1,46 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 09: Garbage Collection */ +/* 01.Table Creation */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'GCDemo' and s.name = 'dbo') drop table dbo.GCDemo; +go + + +/** RESTART SQL SERVER BEFORE THE TEST **/ + +create table dbo.GCDemo +( + ID int not null, + Placeholder char(8000) not null, + + constraint PK_GCDemo + primary key nonclustered hash(ID) + with (bucket_count=16384), +) +with (memory_optimized=on, durability=schema_only) +go + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N4 as t2) -- 65,536 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N5) +insert into dbo.GCDemo(Id, Placeholder) + select Id, Replicate('0',8000) + from ids +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/02,DMVs.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/02,DMVs.sql new file mode 100644 index 0000000..88941d0 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/02,DMVs.sql @@ -0,0 +1,38 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 09: Garbage Collection */ +/* 02.DMVs, which were used in the chapter */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/* Next script uses temporary tables to persists results */ +select + convert(decimal(7,2),memory_allocated_for_table_kb / 1024.) + as [memory allocated for table] + ,convert(decimal(7,2),memory_used_by_table_kb / 1024.) + as [memory used by table] +from + sys.dm_db_xtp_table_memory_stats +where + object_id = object_id(N'dbo.GCDemo'); + +select rows_touched, rows_expired, rows_expired_removed +from sys.dm_db_xtp_index_stats +where object_id = object_id(N'dbo.GCDemo'); + +select + sum(total_enqueues) as [total enqueues] + ,sum(total_dequeues) as [total dequeues] +from + sys.dm_xtp_gc_queue_stats diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/03.GC In Action.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/03.GC In Action.sql new file mode 100644 index 0000000..4e17fb6 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/03.GC In Action.sql @@ -0,0 +1,173 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 09: Garbage Collection */ +/* 03.GC In Action */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +create table #MemStats +( + ActionId int not null identity(1,1), + Action varchar(32) not null, + TblAllocatedMemory int not null, + TblUsedMemory int not null +); + +create table #IdxStats +( + ActionId int not null identity(1,1), + Action varchar(32) not null, + RowsTouched int not null, + RowsExpired int not null, + RowsExpiredRemoved int not null, +); + +create table #GCStats +( + ActionId int not null identity(1,1), + Action varchar(32) not null, + TotalEnqueues int not null, + TotalDequeues int not null, +) +go + +insert into #MemStats(Action,TblAllocatedMemory,TblUsedMemory) + select + 'Initial', memory_allocated_for_table_kb + ,memory_used_by_table_kb + from + sys.dm_db_xtp_table_memory_stats + where + object_id = OBJECT_ID(N'dbo.GCDemo'); + +insert into #IdxStats(Action,RowsTouched,RowsExpired,RowsExpiredRemoved) + select 'Initial', rows_touched, rows_expired, rows_expired_removed + from sys.dm_db_xtp_index_stats + where object_id = OBJECT_ID(N'dbo.GCDemo'); + +insert into #GCStats(Action,TotalEnqueues,TotalDequeues) + select 'Initial', sum(total_enqueues), sum(total_dequeues) + from sys.dm_xtp_gc_queue_stats +go + +declare + @I int = 1 + +while @I <= 1500 -- Change to 32768 to see GC activated based on the load +begin + delete from dbo.GCDemo with (snapshot) where ID = @I + select @I += 1 +end; + +insert into #MemStats(Action,TblAllocatedMemory,TblUsedMemory) + select + 'After Deletion', memory_allocated_for_table_kb + ,memory_used_by_table_kb + from + sys.dm_db_xtp_table_memory_stats + where + object_id = OBJECT_ID(N'dbo.GCDemo'); + +insert into #IdxStats(Action,RowsTouched,RowsExpired,RowsExpiredRemoved) + select 'After Deletion', rows_touched, rows_expired, rows_expired_removed + from sys.dm_db_xtp_index_stats + where object_id = OBJECT_ID(N'dbo.GCDemo'); + +insert into #GCStats(Action,TotalEnqueues,TotalDequeues) + select 'After Deletion', sum(total_enqueues), sum(total_dequeues) + from sys.dm_xtp_gc_queue_stats +go + +select count(*) from dbo.GCDemo; + +insert into #MemStats(Action,TblAllocatedMemory,TblUsedMemory) + select + 'After Scan', memory_allocated_for_table_kb + ,memory_used_by_table_kb + from + sys.dm_db_xtp_table_memory_stats + where + object_id = OBJECT_ID(N'dbo.GCDemo'); + +insert into #IdxStats(Action,RowsTouched,RowsExpired,RowsExpiredRemoved) + select 'After Scan', rows_touched, rows_expired, rows_expired_removed + from sys.dm_db_xtp_index_stats + where object_id = OBJECT_ID(N'dbo.GCDemo'); + +insert into #GCStats(Action,TotalEnqueues,TotalDequeues) + select 'After Scan', sum(total_enqueues), sum(total_dequeues) + from sys.dm_xtp_gc_queue_stats +go + +waitfor delay '00:01:05.000'; + +insert into #MemStats(Action,TblAllocatedMemory,TblUsedMemory) + select + 'After Delay', memory_allocated_for_table_kb + ,memory_used_by_table_kb + from + sys.dm_db_xtp_table_memory_stats + where + object_id = OBJECT_ID(N'dbo.GCDemo'); + +insert into #IdxStats(Action,RowsTouched,RowsExpired,RowsExpiredRemoved) + select 'After Delay', rows_touched, rows_expired, rows_expired_removed + from sys.dm_db_xtp_index_stats + where object_id = OBJECT_ID(N'dbo.GCDemo'); + +insert into #GCStats(Action,TotalEnqueues,TotalDequeues) + select 'After Delay', sum(total_enqueues), sum(total_dequeues) + from sys.dm_xtp_gc_queue_stats +go + +select count(*) from dbo.GCDemo; +go + +insert into #MemStats(Action,TblAllocatedMemory,TblUsedMemory) + select + 'After Second Scan', memory_allocated_for_table_kb + ,memory_used_by_table_kb + from + sys.dm_db_xtp_table_memory_stats + where + object_id = OBJECT_ID(N'dbo.GCDemo'); + +insert into #IdxStats(Action,RowsTouched,RowsExpired,RowsExpiredRemoved) + select 'After Second Scan', rows_touched, rows_expired, rows_expired_removed + from sys.dm_db_xtp_index_stats + where object_id = OBJECT_ID(N'dbo.GCDemo'); + +insert into #GCStats(Action,TotalEnqueues,TotalDequeues) + select 'After Second Scan', sum(total_enqueues), sum(total_dequeues) + from sys.dm_xtp_gc_queue_stats +go + +select + m.Action as Stage + ,convert(decimal(7,2), m.TblAllocatedMemory / 1024.) + as [Alloc Memory] + ,convert(decimal(7,2),m.TblUsedMemory / 1024.) + as [Used Memory] + ,rowstouched as [Touched] + , rowsexpired as [Expired] + , rowsexpiredremoved as Removed + ,totalenqueues as [Enqueues] + ,totaldequeues as [Dequeues] +from + #MemStats m join #IdxStats i on + m.ActionId = i.ActionId + join #GCStats g on + m.ActionId = g.ActionId +order by + m.ActionId diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/09.Chapter 09 (Garbage Collection).ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/09.Chapter 09 (Garbage Collection).ssmssqlproj new file mode 100644 index 0000000..89bbbcf --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/09.Chapter 09 (Garbage Collection)/09.Chapter 09 (Garbage Collection).ssmssqlproj @@ -0,0 +1,33 @@ + + + + + + + + + + + + + 01.Table Creation.sql + + + + + + 02,DMVs.sql + + + + + + 03.GC In Action.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/01.Resource Governor.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/01.Resource Governor.sql new file mode 100644 index 0000000..7652481 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/01.Resource Governor.sql @@ -0,0 +1,54 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 10: Deployment and Management */ +/* 01.Resource Governor */ +/****************************************************************************/ + +set nocount on +go + +use master +go + +if not exists +( + select * from sys.resource_governor_resource_pools where name = 'InMemoryDataPool' +) +begin + create resource pool InMemoryDataPool + with + ( + min_memory_percent=40 + ,max_memory_percent=40 + ); + + alter resource governor reconfigure; +end +go + +-- Binding the database. You need to take DB offline and +-- bring it back offline for the changes to make effects + +exec sys.sp_xtp_bind_db_resource_pool + @database_name = 'InMemoryOLTP2014' + ,@pool_name = 'InMemoryDataPool'; + +alter database InMemoryOLTP2014 set offline; +alter database InMemoryOLTP2014 set online; +go + +-- Remove binding. You need to take DB offline and +-- bring it back offline for the changes to make effects + +exec sys.sp_xtp_unbind_db_resource_pool + @database_name = 'InMemoryOLTP2014'; + +alter database InMemoryOLTP2014 set offline; +alter database InMemoryOLTP2014 set online; +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/02.Populating Test Data.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/02.Populating Test Data.sql new file mode 100644 index 0000000..7129e87 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/02.Populating Test Data.sql @@ -0,0 +1,347 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 10: Deployment and Management */ +/* 02.Populating Test Data for the Chapter */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if not exists (select * from sys.schemas where name = 'Delivery') + exec sp_executesql N'create schema [Delivery]' +go + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertOrder' and s.name = 'Delivery') drop proc Delivery.InsertOrder; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'DeleteCustomer' and s.name = 'Delivery') drop proc Delivery.DeleteCustomer; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Orders' and s.name = 'Delivery') drop table Delivery.Orders; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Customers' and s.name = 'Delivery') drop table Delivery.Customers; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Addresses' and s.name = 'Delivery') drop table Delivery.Addresses; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Services' and s.name = 'Delivery') drop table Delivery.Services; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'RatePlans' and s.name = 'Delivery') drop table Delivery.RatePlans; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Drivers' and s.name = 'Delivery') drop table Delivery.Drivers; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'Rates' and s.name = 'Delivery') drop table Delivery.Rates; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'OrderStatuses' and s.name = 'Delivery') drop table Delivery.OrderStatuses; +go + + +create table Delivery.Orders +( + OrderId int not null identity(1,1) + primary key nonclustered + hash with (bucket_count=1000000), + OrderDate smalldatetime not null, + OrderNum varchar(20) + collate Latin1_General_100_BIN2 not null, + Reference varchar(64) null, + CustomerId int not null, + PickupAddressId int not null, + DeliveryAddressId int not null, + ServiceId int not null, + RatePlanId int not null, + OrderStatusId int not null, + DriverId int null, + Pieces smallint not null, + Amount smallmoney not null, + ModTime datetime not null + constraint DEF_Orders_ModTime + default sysutcdatetime(), + PlaceHolder char(100) not null + constraint DEF_Orders_Placeholder + default 'Placeholder', + + index IDX_Orders_OrderNum + nonclustered hash(OrderNum) + with (bucket_count = 1000000), + + index IDX_Orders_CustomerId + nonclustered hash(CustomerId) + with (bucket_count = 1000000), +) +with (memory_optimized=on, durability=schema_only); +go + +create proc Delivery.InsertOrder +( + @OrderNum varchar(20) + ,@Reference varchar(64) + ,@CustomerId int + ,@PickupAddressId int + ,@DeliveryAddressId int + ,@ServiceId int + ,@RatePlanId int + ,@OrderStatusId int + ,@DriverId int + ,@Pieces smallint + ,@Amount smallmoney +) +with + native_compilation + ,schemabinding + ,execute as owner +as +begin atomic with +( + transaction isolation level = snapshot + ,language = N'English' +) + insert into Delivery.Orders(OrderNum,OrderDate,Reference,CustomerId + ,PickupAddressId,DeliveryAddressId,ServiceId + ,RatePlanId,OrderStatusId,DriverId,Pieces,Amount) + values(@OrderNum,GetDate(),@Reference,@CustomerId + ,@PickupAddressId,@DeliveryAddressId,@ServiceId + ,@RatePlanId,@OrderStatusId,@DriverId,@Pieces,@Amount) +end +go + + +create table Delivery.Customers +( + CustomerID int not null identity(1,1) + primary key nonclustered + hash with (bucket_count=100000), + Name varchar(100) + collate Latin1_General_100_BIN2 not null, + Phone varchar(20) not null, + ContactName varchar(100) not null, + BillingAddress varchar(100) not null, + BillingCity varchar(40) not null, + BillingState char(2) not null, + BillingZip char(5) not null, + DefaultRatePlan int null, + DefaultService int null, + RegionId int not null, + + index IDX_Customers + nonclustered(Name) +) +with (memory_optimized=on, durability=schema_only); +go + + +create table Delivery.Addresses +( + AddressId int not null identity(1,1) + primary key nonclustered + hash with (bucket_count=1000000), + CustomerId int not null, + Address varchar(100) not null, + City varchar(40) not null, + State char(2) not null, + Zip char(5) not null, + Direction varchar(1024) null, + + index IDX_Addresses_CustomerId + nonclustered hash(CustomerId) + with (bucket_count = 100000) +) +with (memory_optimized=on, durability=schema_only); +go + +create table Delivery.Services +( + ServiceID int not null + primary key nonclustered + hash with (bucket_count=256), + Name varchar(40) not null, +) +with (memory_optimized=on, durability=schema_only); +go + +create table Delivery.RatePlans +( + RatePlanID int not null + primary key nonclustered + hash with (bucket_count=256), + Name varchar(40) not null, +) +with (memory_optimized=on, durability=schema_only); +go + +create table Delivery.Rates +( + RatePlanID int not null, + ServiceId int not null, + Rate smallmoney not null, + + primary key nonclustered + hash (RatePlanId, ServiceId) + with (bucket_count=1024), +) +with (memory_optimized=on, durability=schema_only); +go + +create table Delivery.Drivers +( + DriverId int not null identity(1,1) + primary key nonclustered + hash with (bucket_count=1024), + Name varchar(40) + collate Latin1_General_100_BIN2 not null, + + index IDX_Drivers_Name + nonclustered(Name) +) +with (memory_optimized=on, durability=schema_only); +go + +create table Delivery.OrderStatuses +( + OrderStatusId int not null identity(1,1) + primary key nonclustered + hash with (bucket_count=1024), + Name varchar(40) not null, +) +with (memory_optimized=on, durability=schema_only); +go + +create proc Delivery.DeleteCustomer +( + @CustomerId int +) +with + native_compilation + ,schemabinding + ,execute as owner +as +begin atomic with +( + transaction isolation level = snapshot + ,language = N'English' +) + delete from Delivery.Addresses where CustomerId = @CustomerId; + delete from Delivery.Orders where CustomerId = @CustomerId; + delete from Delivery.Customers where CustomerId = @CustomerId; +end +go + +declare + @MaxOrderId int + ,@MaxCustomers int + ,@MaxAddresses int + ,@MaxDrivers int + +select + @MaxOrderId=65536 * 16, @MaxCustomers=25000 + ,@MaxAddresses=20, @MaxDrivers = 125 + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as T1 CROSS JOIN N1 as T2) -- 4 rows +,N3(C) as (select 0 from N2 as T1 CROSS JOIN N2 as T2) -- 16 rows +,N4(C) as (select 0 from N3 as T1 CROSS JOIN N3 as T2) -- 256 rows +,N5(C) as (select 0 from N4 as T1 cross join N4 as T2) -- 65,536 rows +,N6(C) as (select 0 from N5 as T1 cross join N3 as T2) -- 1,048,576 rows +,IDs(ID) as (select row_number() over (order by (select null)) from N6) +,Info(OrderId, CustomerId, OrderDateOffset, RateplanId, ServiceId, Pieces) +as +( + select + ID, ID % @MaxCustomers + 1, ID % (365*24*60) + ,ID % 2 + 1, Id % 3 + 1, ID % 5 + 1 + from IDs + where ID <= @MaxOrderId +) +,Info2(OrderId, OrderDate, OrderNum, CustomerId, RateplanId ,ServiceId + ,Pieces ,PickupAddressId, OrderStatusId, Rate) +as +( + select + OrderId, dateadd(minute, -OrderDateOffset, getdate()) + ,convert(varchar(10),OrderId), CustomerId + ,RatePlanId, ServiceId, Pieces + ,(CustomerId - 1) * @MaxAddresses + OrderId % 20 + ,case + when OrderDateOffset > 5 * 24 * 60 + then 4 + else OrderId % 4 + 1 + end, (OrderID % 5 + 1) * 10. + from Info +) +insert into Delivery.Orders(OrderDate, OrderNum, CustomerId, + PickupAddressId, DeliveryAddressId, ServiceId, RatePlanId, + OrderStatusId, DriverId, Pieces, Amount) +select + o.OrderDate, o.OrderNum, o.CustomerId, o.PickupAddressID + ,case + when o.PickupAddressID % @MaxAddresses = 0 + then o.PickupAddressID + 1 + else o.PickupAddressID - 1 + end, o.ServiceID, o.RateplanId, o.OrderStatusId + ,case + when o.OrderStatusId in (1,4) + then NULL + else OrderId % @MaxDrivers + 1 + end, o.Pieces, o.Rate +from Info2 o +go + + +begin tran + insert into Delivery.OrderStatuses(Name) + select 'NEW' union all + select 'DISPATCHED' union all + select 'IN ROUTE' union all + select 'COMPLETED' + + insert into Delivery.Services(ServiceID,Name) + select 1, 'BASE' union all + select 2, 'RUSH' union all + select 3, '2-HOURS' + + insert into Delivery.RatePlans(RatePlanID, Name) + select 1, 'REGULAR' union all + select 2, 'CORPORATE' + + insert into Delivery.Rates(ServiceId, RatePlanID, Rate) + select 1, 1, 15 union all select 1, 2, 10 union all + select 2, 1, 25 union all select 2, 2, 20 union all + select 3, 1, 35 union all select 3, 2, 30 + + declare + @CustomerId int + ,@AddressId int + + select @CustomerId = 1 + + while @CustomerId <= 50000 + begin + insert into Delivery.Customers(Name, Phone, ContactName, + BillingAddress, BillingCity, BillingState, BillingZip, + DefaultRatePlan, DefaultService, RegionId) + values('Customer # ' + convert(varchar(5), @CustomerId), '813-123-4567', + 'Contact for Customer # ' + convert(varchar(5), @CustomerId),'123 Main Street', + 'Tampa', 'FL','33607',@CustomerId % 3, 1, @CustomerId % 50) + + select @AddressId = 0 + while @AddressId < 5 + begin + insert into Delivery.Addresses(CustomerId,Address,City,State,Zip,Direction) + values(@CustomerId, '456 Main Street', 'Tampa', 'FL', '33607', REPLICATE(' ',200)) + + select @AddressId = @AddressId + 1 + end + select @CustomerId = @CustomerId + 1 + end + + declare + @DriverId int + + select @DriverId = 1 + + while @DriverId <= 100 + begin + insert into Delivery.Drivers(Name) + values('Driver # ' + convert(varchar(5), @DriverId)) + + select @DriverId = @DriverId + 1 + end +commit +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/03.Memory Usage.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/03.Memory Usage.sql new file mode 100644 index 0000000..8b3c782 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/03.Memory Usage.sql @@ -0,0 +1,75 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 10: Deployment and Management */ +/* 03.Monitoring Memory Usage */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +select + ms.object_id + ,s.name + '.' + t.name as [table] + ,ms.memory_allocated_for_table_kb + ,ms.memory_used_by_table_kb + ,ms.memory_allocated_for_indexes_kb + ,ms.memory_used_by_indexes_kb +from + sys.dm_db_xtp_table_memory_stats ms + left outer join sys.tables t on + ms.object_id = t.object_id + left outer join sys.schemas s on + t.schema_id = s.schema_id +order by + ms.memory_allocated_for_table_kb desc +go + +select + mc.object_id + ,s.name + '.' + t.name as [table] + ,i.name as [index] + ,mc.memory_consumer_type_desc + ,mc.memory_consumer_desc + ,convert(decimal(9,3),mc.allocated_bytes / 1024. / 1024.) + as [allocated (MB)] + ,convert(decimal(9,3),mc.used_bytes / 1024. / 1024.) + as [used (MB)] + ,mc.allocation_count +from + sys.dm_db_xtp_memory_consumers mc + left outer join sys.tables t on + mc.object_id = t.object_id + left outer join sys.indexes i on + mc.object_id = i.object_id and + mc.index_id = i.index_id + left outer join sys.schemas s on + t.schema_id = s.schema_id +where -- Greater than 1MB + mc.allocated_bytes > 1048576 +order by + [allocated (MB)] desc +go + +select + memory_consumer_type_desc + ,memory_consumer_desc + ,convert(decimal(9,3),allocated_bytes / 1024. / 1024.) + as [allocated (MB)] + ,convert(decimal(9,3),used_bytes / 1024. / 1024.) + as [used (MB)] + ,allocation_count +from + sys.dm_xtp_system_memory_consumers +order by + [allocated (MB)] desc +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/04.Oldest Trans.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/04.Oldest Trans.sql new file mode 100644 index 0000000..ec3b6ba --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/04.Oldest Trans.sql @@ -0,0 +1,46 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 10: Deployment and Management */ +/* 04.Monitoring Active Transactions */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +select top 5 + t.session_id + ,t.xtp_transaction_id + ,t.transaction_id + ,t.begin_tsn + ,t.end_tsn + ,t.state_desc + ,t.result_desc + ,substring( + qt.text + ,er.statement_start_offset / 2 + 1 + ,(case er.statement_end_offset + when -1 then datalength(qt.text) + else er.statement_end_offset + end - er.statement_start_offset + ) / 2 +1 + ) as SQL +from + sys.dm_db_xtp_transactions t + left join sys.dm_exec_requests er on + t.session_id = er.session_id + outer apply + sys.dm_exec_sql_text(er.sql_handle) qt +where + t.state in (0,3) /* ACTIVE/VALIDATING */ +order by + t.begin_tsn +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/05.Execution Statistics.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/05.Execution Statistics.sql new file mode 100644 index 0000000..d19f040 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/05.Execution Statistics.sql @@ -0,0 +1,72 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 10: Deployment and Management */ +/* 05.Execution Statistics */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/*** Enable Execution Statistics Collection. Do not keep enabled on production server ***/ +exec sys.sp_xtp_control_proc_exec_stats 1; +exec sys.sp_xtp_control_query_exec_stats 1; +go + +select + object_name(object_id) as [Proc Name] + ,execution_count as [Exec Cnt] + ,total_worker_time as [Total CPU] + ,convert(int,total_worker_time / 1000 / execution_count) + as [Avg CPU] -- in Milliseconds + ,total_elapsed_time as [Total Elps] + ,convert(int,total_elapsed_time / 1000 / execution_count) + as [Avg Elps] -- in Milliseconds + ,cached_time as [Cached] + ,last_execution_time as [Last Exec] + ,sql_handle + ,plan_handle + ,total_logical_reads as [Reads] + ,total_logical_writes as [Writes] +from + sys.dm_exec_procedure_stats +order by + [AVG CPU] desc +go + +select + substring(qt.text + ,(qs.statement_start_offset/2) + 1 + ,(case qs.statement_end_offset + when -1 then datalength(qt.text) + else qs.statement_end_offset + end - qs.statement_start_offset) / 2 + 1 + ) as SQL + ,qs.execution_count as [Exec Cnt] + ,qs.total_worker_time as [Total CPU] + ,convert(int,qs.total_worker_time / 1000 / qs.execution_count) + as [Avg CPU] -- in Milliseconds + ,total_elapsed_time as [Total Elps] + ,convert(int,qs.total_elapsed_time / 1000 / qs.execution_count) + as [Avg Elps] -- in Milliseconds + ,qs.creation_time as [Cached] + ,last_execution_time as [Last Exec] + ,qs.plan_handle + ,qs.total_logical_reads as [Reads] + ,qs.total_logical_writes as [Writes] +from + sys.dm_exec_query_stats qs + outer apply sys.dm_exec_sql_text(qs.sql_handle) qt +where + qs.plan_generation_num is null +order by + [AVG CPU] desc +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/06.Hash Indexes with Suboptimal Bucket_Count.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/06.Hash Indexes with Suboptimal Bucket_Count.sql new file mode 100644 index 0000000..83abe9b --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/06.Hash Indexes with Suboptimal Bucket_Count.sql @@ -0,0 +1,43 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 10: Deployment and Management */ +/* 06.Detecting Hash Indexes with Suboptimal bucket_count */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +-- You can consider to change predicates based on your workload and use-cases + +select + s.name + '.' + t.name as [Table] + ,i.name as [Index] + ,stat.total_bucket_count as [Total Buckets] + ,stat.empty_bucket_count as [Empty Buckets] + ,floor(100. * empty_bucket_count / total_bucket_count) + as [Empty Bucket %] + ,stat.avg_chain_length as [Avg Chain] + ,stat.max_chain_length as [Max Chain] +from + sys.dm_db_xtp_hash_index_stats stat + join sys.tables t on + stat.object_id = t.object_id + join sys.indexes i on + stat.object_id = i.object_id and + stat.index_id = i.index_id + join sys.schemas s on + t.schema_id = s.schema_id +where + stat.avg_chain_length > 3 or + stat.max_chain_length > 50 or + floor(100. * empty_bucket_count / total_bucket_count) > 50 +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/07.xEvents and Perf Counters.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/07.xEvents and Perf Counters.sql new file mode 100644 index 0000000..0cbcade --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/07.xEvents and Perf Counters.sql @@ -0,0 +1,37 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 10: Deployment and Management */ +/* 07.Exploring In-Memory OLTP xEvents and Perf. Counters */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +select + xp.name as [package] + ,xo.name as [event] + ,xo.description as [description] +from + sys.dm_xe_packages xp + join sys.dm_xe_objects xo on + xp.guid = xo.package_guid +where + xp.name like 'XTP%' +order by + xp.name, xo.name +go + +select object_name, counter_name +from sys.dm_os_performance_counters +where object_name like 'XTP%' +order by object_name, counter_name +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/10.Chapter 10 (Deployment and Management).ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/10.Chapter 10 (Deployment and Management).ssmssqlproj new file mode 100644 index 0000000..3084c73 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/10.Chapter 10 (Deployment and Management)/10.Chapter 10 (Deployment and Management).ssmssqlproj @@ -0,0 +1,57 @@ + + + + + + + + + + + + + 01.Resource Governor.sql + + + + + + 02.Populating Test Data.sql + + + + + + 03.Memory Usage.sql + + + + + + 04.Oldest Trans.sql + + + + + + 05.Execution Statistics.sql + + + + + + 06.Hash Indexes with Suboptimal Bucket_Count.sql + + + + + + 07.xEvents and Perf Counters.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/01.Vertical Partitioning.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/01.Vertical Partitioning.sql new file mode 100644 index 0000000..47b8c8f --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/01.Vertical Partitioning.sql @@ -0,0 +1,78 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/*01.Example of Vertical Partitioning (Addressing 8,060-byte row size limit)*/ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertProduct' and s.name = 'dbo') drop proc dbo.InsertProduct; +if exists(select * from sys.views v join sys.schemas s on v.schema_id = s.schema_id where s.name = 'dbo' and v.name = 'Products') drop view dbo.Products; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'ProductsInMem') drop table dbo.ProductsInMem; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'ProductAttributes') drop table dbo.ProductAttributes; +go + +/* +create table dbo.Products +( + ProductId int not null identity(1,1), + ProductName nvarchar(64) not null, + ShortDescription nvarchar(256) not null, + Description nvarchar(max) not null, + Picture varbinary(max) null, + + constraint PK_Products + primary key clustered(ProductId) +) +*/ + +create table dbo.ProductsInMem +( + ProductId int not null identity(1,1) + constraint PK_ProductsInMem + primary key nonclustered hash + with (bucket_count = 65536), + ProductName nvarchar(64) + collate Latin1_General_100_BIN2 not null, + ShortDescription nvarchar(256) not null, + + index IDX_ProductsInMem_ProductName nonclustered(ProductName) +) +with (memory_optimized = on, durability = schema_and_data); + +create table dbo.ProductAttributes +( + ProductId int not null, + Description nvarchar(max) not null, + Picture varbinary(max) null, + + constraint PK_ProductAttributes + primary key clustered(ProductId) +); +go + +create view dbo.Products(ProductId, ProductName, + ShortDescription, Description, Picture) +as + select + p.ProductId, p.ProductName, p.ShortDescription + ,pa.Description, pa.Picture + from + dbo.ProductsInMem p left outer join + dbo.ProductAttributes pa on + p.ProductId = pa.ProductId; +go + +select ProductId, ProductName +from dbo.Products; + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/02.Splitting Data.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/02.Splitting Data.sql new file mode 100644 index 0000000..608b4e7 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/02.Splitting Data.sql @@ -0,0 +1,100 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 02.Splitting Data (Addressing 8,060-byte row size limit) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if object_id(N'dbo.SplitData','IF') is not null drop function dbo.SplitData; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'LOBData') drop table dbo.LOBData; +go + +create table dbo.LOBData +( + ObjectId int not null, + PartNo smallint not null, + Data varbinary(8000) not null, + + constraint PK_LobData + primary key nonclustered hash(ObjectID, PartNo) + with (bucket_count=1048576), + + index IDX_ObjectID + nonclustered hash(ObjectID) + with (bucket_count=1048576) +) +with (memory_optimized = on, durability = schema_and_data); +go + +create function dbo.SplitData +( + @LobData varbinary(max) +) +returns table +as +return +( + with Parts(Start, Data) + as + ( + select 1, substring(@LobData,1,8000) + where @LobData is not null + + union all + + select Start + 8000, substring(@LobData,Start + 8000,8000) + from Parts + where len(substring(@LobData,Start + 8000,8000)) > 0 + ) + select + row_number() over(order by Start) as PartNo + ,Data + from + Parts +) +go + +declare + @X xml + +select @X = + (select * from master.sys.objects for xml raw); + +insert into dbo.LobData(ObjectId, PartNo, Data) + select 1, PartNo, Data + from dbo.SplitData(convert(varbinary(max),@X)) +-- option (maxrecursion 0); +go + +select ObjectId, PartNo, Data +from dbo.LobData +where ObjectId = 1 +order by PartNo; +go + +;with ConcatData(BinaryData) +as +( + select + convert(varbinary(max), + ( + select convert(varchar(max),Data,2) as [text()] + from dbo.LobData + where ObjectId = 1 + order by PartNo + for xml path('') + ),2) +) +select convert(xml,BinaryData) +from ConcatData; diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/03.1.Uniqueness Support.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/03.1.Uniqueness Support.sql new file mode 100644 index 0000000..b90483a --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/03.1.Uniqueness Support.sql @@ -0,0 +1,79 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 03.Enforcing Uniqueness (Session 1) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'InsertProduct') drop proc dbo.InsertProduct; +go + +if not exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'ProductsInMem') +begin + raiserror('Please create dbo.ProductsInMem table using "01.Vertical Partitioning.sql" script',16,1) + set noexec on +end +go + +create procedure dbo.InsertProduct +( + @ProductName nvarchar(64) not null + ,@ShortDescription nvarchar(256) not null + ,@ProductId int output +) +with native_compilation, schemabinding, execute as owner +as +begin atomic with +( + transaction isolation level = serializable + ,language = N'English' +) + declare + @Exists bit = 0 + + -- Building scan set and checking + -- existense of the product + select @Exists = 1 + from dbo.ProductsInMem + where ProductName = @ProductName + + if @Exists = 1 + begin + ;throw 50000, 'Product Already Exists', 1; + return + end + + insert into dbo.ProductsInMem(ProductName, ShortDescription) + values(@ProductName, @ShortDescription); + + select @ProductID = scope_identity() +end +go + +-- Session 1 code +declare + @ProductId int + +-- Running in transaction to simulate concurrent execution +begin tran + exec dbo.InsertProduct + 'Expert SQL Server In-Memory OLTP' + ,'Published by APress' + ,@ProductId output; + + -- Run Session 2 code +commit + + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/03.2.Uniqueness Support.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/03.2.Uniqueness Support.sql new file mode 100644 index 0000000..d5cd621 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/03.2.Uniqueness Support.sql @@ -0,0 +1,26 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 03.Enforcing Uniqueness (Session 2) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +declare + @ProductId int + +exec dbo.InsertProduct + 'Expert SQL Server In-Memory OLTP' + ,'Published by APress' + ,@ProductId output; diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/04.Referential Integrity.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/04.Referential Integrity.sql new file mode 100644 index 0000000..c17003f --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/04.Referential Integrity.sql @@ -0,0 +1,140 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 04.Enforcing Referential Integrity */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertOrders' and s.name = 'dbo') drop proc dbo.InsertOrders; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'GetTopCustomers' and s.name = 'dbo') drop proc dbo.GetTopCustomers; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'DeleteCustomersAndOrders' and s.name = 'dbo') drop proc dbo.DeleteCustomersAndOrders; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'InsertOrderLineItems') drop proc dbo.InsertOrderLineItems; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'DeleteOrder') drop proc dbo.DeleteOrder; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'Orders') drop table dbo.Orders; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'OrderLineItems') drop table dbo.OrderLineItems; +if exists(select * from sys.table_types t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'tvpOrderLineItems') drop type dbo.tvpOrderLineItems; +go + +create table dbo.Orders +( + OrderId int not null identity(1,1) + constraint PK_Orders + primary key nonclustered hash + with (bucket_count=1000000), + OrderNum varchar(32) + collate Latin1_General_100_BIN2 not null, + OrderDate datetime2(0) not null + constraint DEF_Orders_OrderDate + default GetUtcDate(), + /* Other Columns */ + index IDX_Orders_OrderNum + nonclustered(OrderNum) +) +with (memory_optimized = on, durability = schema_and_data); + +create table dbo.OrderLineItems +( + OrderId int not null, + OrderLineItemId int not null identity(1,1) + constraint PK_OrderLineItems + primary key nonclustered hash + with (bucket_count=10000000), + ArticleId int not null, + Quantity decimal(8,2) not null, + Price money not null, + /* Other Columns */ + + index IDX_OrderLineItems_OrderId + nonclustered hash(OrderId) + with (bucket_count=1000000) +) +with (memory_optimized = on, durability = schema_and_data); +go + +create type dbo.tvpOrderLineItems as table +( + ArticleId int not null + primary key nonclustered hash + with (bucket_count = 1024), + Quantity decimal(8,2) not null, + Price money not null + /* Other Columns */ +) +with (memory_optimized = on); +go + +create proc dbo.DeleteOrder +( + @OrderId int not null +) +with native_compilation, schemabinding, execute as owner +as +begin atomic +with +( + transaction isolation level = serializable + ,language=N'English' +) + -- This stored procedure emulates ON DELETE NO ACTION + -- foreign key constraint behavior + declare + @Exists bit = 0 + + select @Exists = 1 + from dbo.OrderLineItems + where OrderId = @OrderId + + if @Exists = 1 + begin + ;throw 60000, 'Referential Integrity Violation', 1; + return + end + + delete from dbo.Orders where OrderId = @OrderId +end +go + +create proc dbo.InsertOrderLineItems +( + @OrderId int not null + ,@OrderLineItems dbo.tvpOrderLineItems readonly +) +with native_compilation, schemabinding, execute as owner +as +begin atomic +with +( + transaction isolation level = repeatable read + ,language=N'English' +) + declare + @Exists bit = 0 + + select @Exists = 1 + from dbo.Orders + where OrderId = @OrderId + + if @Exists = 0 + begin + ;throw 60001, 'Referential Integrity Violation', 1; + return + end + + insert into dbo.OrderLineItems(OrderId, ArticleId, Quantity, Price) + select @OrderId, ArticleId, Quantity, Price + from @OrderLineItems +end +go + + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/05.Binary Collation.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/05.Binary Collation.sql new file mode 100644 index 0000000..db2384e --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/05.Binary Collation.sql @@ -0,0 +1,116 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 05.Binary Collation Performance */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'CollationTest') drop table dbo.CollationTest; +if object_id(N'tempdb..#CollData') is not null drop table #CollData; +go + +create table dbo.CollationTest +( + ID int not null, + VarCol varchar(108) not null, + NVarCol nvarchar(108) not null, + VarColBin varchar(108) + collate Latin1_General_100_BIN2 not null, + NVarColBin nvarchar(108) + collate Latin1_General_100_BIN2 not null, + + constraint PK_CollationTest + primary key nonclustered hash(ID) + with (bucket_count=131072), + +) +with (memory_optimized=on, durability=schema_only) +go + +create table #CollData +( + ID int not null, + Col1 uniqueidentifier not null + default NEWID(), + Col2 uniqueidentifier not null + default NEWID(), + Col3 uniqueidentifier not null + default NEWID() +) +go + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as T1 cross join N1 as T2) -- 4 rows +,N3(C) as (select 0 from N2 as T1 cross join N2 as T2) -- 16 rows +,N4(C) as (select 0 from N3 as T1 cross join N3 as T2) -- 256 rows +,N5(C) as (select 0 from N4 as T1 cross join N4 as T2) -- 65,536 rows +,IDs(ID) as (select row_number() over (order by (select NULL)) from N5) +insert into #CollData(ID) + select ID from IDs; + +insert into dbo.CollationTest(ID,VarCol,NVarCol,VarColBin,NVarColBin) + select + ID, + /* VarCol */ + convert(varchar(36),Col1) + + convert(varchar(36),Col2) + + convert(varchar(36),Col3), + /* NVarCol */ + convert(nvarchar(36),Col1) + + convert(nvarchar(36),Col2) + + convert(nvarchar(36),Col3), + /* VarColBin */ + convert(varchar(36),Col1) + + convert(varchar(36),Col2) + + convert(varchar(36),Col3), + /* NVarColBin */ + convert(nvarchar(36),Col1) + + convert(nvarchar(36),Col2) + + convert(nvarchar(36),Col3) + from + #CollData +go + +declare + @Param varchar(16) + ,@NParam varchar(16) + +select + @Param = substring(VarCol,43,6) + ,@NParam = substring(NVarCol,43,6) +from + dbo.CollationTest +where + ID = 1000; + +set statistics time on + +select count(*) +from dbo.CollationTest +where VarCol like '%' + @Param + '%'; + +select count(*) +from dbo.CollationTest +where NVarCol like '%' + @NParam + N'%'; + +select count(*) +from dbo.CollationTest +where VarColBin like '%' + upper(@Param) + '%' collate Latin1_General_100_Bin2; + +select count(*) +from dbo.CollationTest +where NVarColBin like '%' + upper(@NParam) + N'%' collate Latin1_General_100_Bin2; + +set statistics time off +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/06.TVP.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/06.TVP.sql new file mode 100644 index 0000000..8d1e5c1 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/06.TVP.sql @@ -0,0 +1,315 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 06.Batch Insert Performance */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/****************************************************************************/ +/* This script prepares the database schema for SaveRecordSetApp demo app */ +/****************************************************************************/ + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertDataRecordsTVP' and s.name = 'dbo') drop proc dbo.InsertDataRecordsTVP; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertDataRecordsElementsXml' and s.name = 'dbo') drop proc dbo.InsertDataRecordsElementsXml; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertDataRecordsAttrXml' and s.name = 'dbo') drop proc dbo.InsertDataRecordsAttrXml; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertDataRecordsOpenXML' and s.name = 'dbo') drop proc dbo.InsertDataRecordsOpenXML; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where p.name = 'InsertDataRecordsAttrXml2' and s.name = 'dbo') drop proc dbo.InsertDataRecordsAttrXml2; +if exists(select * from sys.types t join sys.schemas s on t.schema_id = s.schema_id where t.name = 'DataRecordsTVP' and s.name = 'dbo') drop type dbo.DataRecordsTVP; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'DataRecords') drop table dbo.DataRecords; +go + +create table dbo.DataRecords +( + ID int not null, + Col1 varchar(20) not null, + Col2 varchar(20) not null, + Col3 varchar(20) not null, + Col4 varchar(20) not null, + Col5 varchar(20) not null, + Col6 varchar(20) not null, + Col7 varchar(20) not null, + Col8 varchar(20) not null, + Col9 varchar(20) not null, + Col10 varchar(20) not null, + Col11 varchar(20) not null, + Col12 varchar(20) not null, + Col13 varchar(20) not null, + Col14 varchar(20) not null, + Col15 varchar(20) not null, + Col16 varchar(20) not null, + Col17 varchar(20) not null, + Col18 varchar(20) not null, + Col19 varchar(20) not null, + Col20 varchar(20) not null, + + constraint PK_DataRecords + primary key clustered(ID) +) +go + + +create type dbo.DataRecordsTVP as Table +( + ID int not null, + Col1 varchar(20) not null, + Col2 varchar(20) not null, + Col3 varchar(20) not null, + Col4 varchar(20) not null, + Col5 varchar(20) not null, + Col6 varchar(20) not null, + Col7 varchar(20) not null, + Col8 varchar(20) not null, + Col9 varchar(20) not null, + Col10 varchar(20) not null, + Col11 varchar(20) not null, + Col12 varchar(20) not null, + Col13 varchar(20) not null, + Col14 varchar(20) not null, + Col15 varchar(20) not null, + Col16 varchar(20) not null, + Col17 varchar(20) not null, + Col18 varchar(20) not null, + Col19 varchar(20) not null, + Col20 varchar(20) not null, + + primary key(ID) + --primary key nonclustered hash(ID) with (bucket_count=65536) +) +--with (memory_optimized=on); +go + +create proc dbo.InsertDataRecordsTVP +( + @Data dbo.DataRecordsTVP READONLY +) +as +begin + set xact_abort on + set transaction isolation level read committed + set nocount on + + begin tran + insert into dbo.DataRecords(ID,Col1,Col2,Col3,Col4,Col5, + Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13, + Col14,Col15,Col16,Col17,Col18,Col19,Col20) + select ID,Col1,Col2,Col3,Col4,Col5, + Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13, + Col14,Col15,Col16,Col17,Col18,Col19,Col20 + from @Data + commit +end +go + +create proc dbo.InsertDataRecordsElementsXml +( + @Data xml +) +as +begin + set xact_abort on + set transaction isolation level read committed + set nocount on + + begin tran + insert into dbo.DataRecords(ID,Col1,Col2,Col3,Col4,Col5, + Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13, + Col14,Col15,Col16,Col17,Col18,Col19,Col20) + SELECT + Rows.n.value('ID[1]', 'int') + ,Rows.n.value('F1[1]', 'varchar(20)') + ,Rows.n.value('F2[1]', 'varchar(20)') + ,Rows.n.value('F3[1]', 'varchar(20)') + ,Rows.n.value('F4[1]', 'varchar(20)') + ,Rows.n.value('F5[1]', 'varchar(20)') + ,Rows.n.value('F6[1]', 'varchar(20)') + ,Rows.n.value('F7[1]', 'varchar(20)') + ,Rows.n.value('F8[1]', 'varchar(20)') + ,Rows.n.value('F9[1]', 'varchar(20)') + ,Rows.n.value('F10[1]', 'varchar(20)') + ,Rows.n.value('F11[1]', 'varchar(20)') + ,Rows.n.value('F12[1]', 'varchar(20)') + ,Rows.n.value('F13[1]', 'varchar(20)') + ,Rows.n.value('F14[1]', 'varchar(20)') + ,Rows.n.value('F15[1]', 'varchar(20)') + ,Rows.n.value('F16[1]', 'varchar(20)') + ,Rows.n.value('F17[1]', 'varchar(20)') + ,Rows.n.value('F18[1]', 'varchar(20)') + ,Rows.n.value('F19[1]', 'varchar(20)') + ,Rows.n.value('F20[1]', 'varchar(20)') + FROM + @Data.nodes('//Recs/R') Rows(n) + commit +end +go + +create proc dbo.InsertDataRecordsAttrXml +( + @Data xml +) +as +begin + set xact_abort on + set transaction isolation level read committed + set nocount on + + begin tran + insert into dbo.DataRecords(ID,Col1,Col2,Col3,Col4,Col5, + Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13, + Col14,Col15,Col16,Col17,Col18,Col19,Col20) + SELECT + Rows.n.value('@ID[1]', 'int') + ,Rows.n.value('@F1[1]', 'varchar(20)') + ,Rows.n.value('@F2[1]', 'varchar(20)') + ,Rows.n.value('@F3[1]', 'varchar(20)') + ,Rows.n.value('@F4[1]', 'varchar(20)') + ,Rows.n.value('@F5[1]', 'varchar(20)') + ,Rows.n.value('@F6[1]', 'varchar(20)') + ,Rows.n.value('@F7[1]', 'varchar(20)') + ,Rows.n.value('@F8[1]', 'varchar(20)') + ,Rows.n.value('@F9[1]', 'varchar(20)') + ,Rows.n.value('@F10[1]', 'varchar(20)') + ,Rows.n.value('@F11[1]', 'varchar(20)') + ,Rows.n.value('@F12[1]', 'varchar(20)') + ,Rows.n.value('@F13[1]', 'varchar(20)') + ,Rows.n.value('@F14[1]', 'varchar(20)') + ,Rows.n.value('@F15[1]', 'varchar(20)') + ,Rows.n.value('@F16[1]', 'varchar(20)') + ,Rows.n.value('@F17[1]', 'varchar(20)') + ,Rows.n.value('@F18[1]', 'varchar(20)') + ,Rows.n.value('@F19[1]', 'varchar(20)') + ,Rows.n.value('@F20[1]', 'varchar(20)') + FROM + @Data.nodes('//Recs/R') Rows(n) + commit +end +go + +create proc dbo.InsertDataRecordsOpenXML +( + @Data xml +) +as +begin + set xact_abort on + set transaction isolation level read committed + set nocount on + + declare + @Result int + ,@Handle int + + exec @Result = sp_xml_preparedocument @Handle output, @Data + if (@Result <> 0) + begin + raiserror('Cannot get xml handle',17,1); + return + end + + begin tran + insert into dbo.DataRecords(ID,Col1,Col2,Col3,Col4,Col5, + Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13, + Col14,Col15,Col16,Col17,Col18,Col19,Col20) + SELECT + ID, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, + F11, F12, F13, F14, F15, F16, F17, F18, F19, F20 + from + OPENXML (@Handle, '/Recs/R',1) + with + (ID int, F1 varchar(20), F2 varchar(20), F3 varchar(20), + F4 varchar(20), F5 varchar(20), F6 varchar(20), F7 varchar(20), + F8 varchar(20), F9 varchar(20), F10 varchar(20), F11 varchar(20), + F12 varchar(20), F13 varchar(20), F14 varchar(20), F15 varchar(20), + F16 varchar(20), F17 varchar(20), F18 varchar(20), F19 varchar(20), + F20 varchar(20)) + commit + exec sp_xml_removedocument @Handle +end +go + +create proc dbo.InsertDataRecordsAttrXml2 +( + @Data xml +) +as +begin + set xact_abort on + set transaction isolation level read committed + set nocount on + + declare + @Temp table + ( + ID int not null, + Col1 varchar(20) not null, + Col2 varchar(20) not null, + Col3 varchar(20) not null, + Col4 varchar(20) not null, + Col5 varchar(20) not null, + Col6 varchar(20) not null, + Col7 varchar(20) not null, + Col8 varchar(20) not null, + Col9 varchar(20) not null, + Col10 varchar(20) not null, + Col11 varchar(20) not null, + Col12 varchar(20) not null, + Col13 varchar(20) not null, + Col14 varchar(20) not null, + Col15 varchar(20) not null, + Col16 varchar(20) not null, + Col17 varchar(20) not null, + Col18 varchar(20) not null, + Col19 varchar(20) not null, + Col20 varchar(20) not null + ) + + insert into @Temp(ID,Col1,Col2,Col3,Col4,Col5, + Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13, + Col14,Col15,Col16,Col17,Col18,Col19,Col20) + SELECT + Rows.n.value('@ID[1]', 'int') + ,Rows.n.value('@F1[1]', 'varchar(20)') + ,Rows.n.value('@F2[1]', 'varchar(20)') + ,Rows.n.value('@F3[1]', 'varchar(20)') + ,Rows.n.value('@F4[1]', 'varchar(20)') + ,Rows.n.value('@F5[1]', 'varchar(20)') + ,Rows.n.value('@F6[1]', 'varchar(20)') + ,Rows.n.value('@F7[1]', 'varchar(20)') + ,Rows.n.value('@F8[1]', 'varchar(20)') + ,Rows.n.value('@F9[1]', 'varchar(20)') + ,Rows.n.value('@F10[1]', 'varchar(20)') + ,Rows.n.value('@F11[1]', 'varchar(20)') + ,Rows.n.value('@F12[1]', 'varchar(20)') + ,Rows.n.value('@F13[1]', 'varchar(20)') + ,Rows.n.value('@F14[1]', 'varchar(20)') + ,Rows.n.value('@F15[1]', 'varchar(20)') + ,Rows.n.value('@F16[1]', 'varchar(20)') + ,Rows.n.value('@F17[1]', 'varchar(20)') + ,Rows.n.value('@F18[1]', 'varchar(20)') + ,Rows.n.value('@F19[1]', 'varchar(20)') + ,Rows.n.value('@F20[1]', 'varchar(20)') + FROM + @Data.nodes('//Recs/R') Rows(n) + + begin tran + insert into dbo.DataRecords(ID,Col1,Col2,Col3,Col4,Col5, + Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13, + Col14,Col15,Col16,Col17,Col18,Col19,Col20) + SELECT + ID,Col1,Col2,Col3,Col4,Col5, + Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13, + Col14,Col15,Col16,Col17,Col18,Col19,Col20 + from @Temp + commit +end +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/07.TV Performance OLTP.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/07.TV Performance OLTP.sql new file mode 100644 index 0000000..ae53cbb --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/07.TV Performance OLTP.sql @@ -0,0 +1,175 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 07.Memory-Optimized Table Variable Performance (OLTP) */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'TestTempVars') drop proc dbo.TestTempVars; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'TestTempTables') drop proc dbo.TestTempTables; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'TestInMemTempTables') drop proc dbo.TestInMemTempTables; +if exists(select * from sys.table_types t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'InMemTV') drop type dbo.InMemTV; +go + +create type dbo.InMemTV as table +( + Id int not null + primary key nonclustered hash + with (bucket_count=512), + Placeholder char(255) +) +with (memory_optimized=on) +go + +create proc dbo.TestInMemTempTables(@Rows int) +as + declare + @ttTemp dbo.InMemTV + ,@Cnt int + + ;with N1(C) as (select 0 union all select 0) -- 2 rows + ,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows + ,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows + ,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows + ,Ids(Id) as (select row_number() over (order by (select null)) from N4) + insert into @ttTemp (Id) + select Id from Ids where Id <= @Rows; + + select @Cnt = count(*) from @ttTemp +go + + +create proc dbo.TestTempTables(@Rows int) +as + declare + @Cnt int + + create table #TTTemp + ( + Id int not null primary key, + Placeholder char(255) + ) + + ;with N1(C) as (select 0 union all select 0) -- 2 rows + ,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows + ,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows + ,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows + ,Ids(Id) as (select row_number() over (order by (select null)) from N4) + insert into #TTTemp (Id) + select Id from Ids where Id <= @Rows; + + select @Cnt = count(*) from #TTTemp +go + + +create proc dbo.TestTempVars(@Rows int) +as + declare + @Cnt int + + declare + @ttTemp table + ( + Id int not null primary key, + Placeholder char(255) + ) + + ;with N1(C) as (select 0 union all select 0) -- 2 rows + ,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows + ,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows + ,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows + ,Ids(Id) as (select row_number() over (order by (select null)) from N4) + insert into @ttTemp (Id) + select Id from Ids where Id <= @Rows; + + select @Cnt = count(*) from @ttTemp +go + +declare + @Result table + ( + [Rows] int not null primary key, + InMemTV int not null, + TempTbl int not null, + OnDiskTV int not null + ); + +declare + @PacketSize int = 16 + ,@LoopCnt int = 5000 + ,@I int = 0 + ,@DT datetime + ,@InMemTV int + ,@TempTbl int + ,@OnDiskTV int + +while @PacketSize <= 256 +begin + select @DT = getDate(), @I = 0; + while @I < @LoopCnt + begin + exec dbo.TestInMemTempTables @PacketSize; + set @I += 1; + end; + select @InMemTV = datediff(millisecond,@DT,GetDate()); + + select @I = 0, @DT = getdate(); + while @I < @LoopCnt + begin + exec dbo.TestTempTables @PacketSize; + set @I += 1; + end; + select @TempTbl = datediff(millisecond,@DT,GetDate()); + + select @I = 0, @DT = getdate(); + while @I < @LoopCnt + begin + exec dbo.TestTempVars @PacketSize; + set @I += 1; + end; + select @OnDiskTV = datediff(millisecond,@DT,GetDate()); + + insert into @Result([Rows],InMemTV,TempTbl,OnDiskTV) + values(@PacketSize,@InMemTV,@TempTbl,@OnDiskTV); + select @PacketSize *= 2; +end; + +select * from @Result order by [Rows]; +go + +/* Checking Cardinality Estimations */ +declare + @InMemTV dbo.InMemTV; + +declare + @ttTemp table + ( + Id int not null primary key, + Placeholder char(255) + ); + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N4) +insert into @InMemTV(Id) + select Id from Ids; + +insert into @ttTemp + select * from @InMemTV; + +select count(*) from @ttTemp; -- option (recompile); +select count(*) from @InMemTV; -- option (recompile); \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/08.1.TV Performance DW - Create.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/08.1.TV Performance DW - Create.sql new file mode 100644 index 0000000..345d601 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/08.1.TV Performance DW - Create.sql @@ -0,0 +1,154 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 08.Memory-Optimized Table Variable Performance (DW) - Create Tables */ +/****************************************************************************/ + +set noexec off +go + +set nocount on +go + +use InMemoryOLTP2014 +go + +if not exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'InputData') +begin + raiserror('Create dbo.InputData table using scripts/data from ETL subfolder',16,1); + set noexec on +end +go + +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dw' and t.name = 'FactSales') drop table dw.FactSales; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dw' and t.name = 'DimDates') drop table dw.DimDates; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dw' and t.name = 'DimProducts') drop table dw.DimProducts; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dw' and t.name = 'FactSalesETLDisk') drop table dw.FactSalesETLDisk; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dw' and t.name = 'FactSalesETLMem') drop table dw.FactSalesETLMem; +go + +if not exists(select * from sys.schemas where name = 'dw') + exec sp_executesql N'create schema dw authorization dbo' +go + +create table dw.DimDates +( + ADateId int identity(1,1) not null, + ADate date not null, + ADay tinyint not null, + AMonth tinyint not null, + AnYear smallint not null, + ADayOfWeek tinyint not null, + + constraint PK_DimDates + primary key clustered(ADateId) +); + +declare + @MinDate date = '2013-01-01' + +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N3 as t2) -- 4,096 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N5) +,Dates(ADate) as ( select dateadd(day,Id,@MinDate) from Ids) +insert into dw.DimDates(ADate,ADay,AMonth,AnYear,ADayOfWeek) + select ADate,day(ADate),month(ADate),year(ADate),datepart(dw,ADate) + from Dates +go + + +create unique nonclustered index IDX_DimDates_ADate +on dw.DimDates(ADate); + +create table dw.DimProducts +( + ProductId int identity(1,1) not null, + Product nvarchar(64) not null, + ProductBin nvarchar(64) + collate Latin1_General_100_BIN2 + not null, + + constraint PK_DimProducts + primary key clustered(ProductId) +); + +insert into dw.DimProducts(Product,ProductBin) + select distinct Product, Product + from dbo.InputData; + +create unique nonclustered index IDX_DimProducts_Product +on dw.DimProducts(Product); + +create unique nonclustered index IDX_DimProducts_ProductBin +on dw.DimProducts(ProductBin); + +create table dw.FactSales +( + ADateId int not null, + ProductId int not null, + OrderId int not null, + OrderNum varchar(32) not null, + Quantity decimal(9,3) not null, + UnitPrice money not null, + Amount money not null, + + constraint PK_FactSales + primary key (ADateId,ProductId,OrderId), + + constraint FK_FactSales_DimDates + foreign key(ADateId) + references dw.DimDates(ADateId), + + constraint FK_FactSales_DimProducts + foreign key(ProductId) + references dw.DimProducts(ProductId) +); + + +create table dw.FactSalesETLDisk +( + OrderId int not null, + OrderNum varchar(32) not null, + Product nvarchar(64) not null, + ADate date not null, + Quantity decimal(9,3) not null, + UnitPrice money not null, + Amount money not null, + /* Optional Placeholder Column */ + --Placeholder char(255) null, + primary key (OrderId, Product) +) +go + +create table dw.FactSalesETLMem +( + OrderId int not null, + OrderNum varchar(32) not null, + Product nvarchar(64) + collate Latin1_General_100_BIN2 not null, + ADate date not null, + Quantity decimal(9,3) not null, + UnitPrice money not null, + Amount money not null, + /* Optional Placeholder Column */ + --Placeholder char(255) null, + + constraint PK_FactSalesETLMem + primary key nonclustered hash(OrderId, Product) + with (bucket_count = 2000000) + + /* Optional Index */ + --,index IDX_Product nonclustered(Product) +) +with (memory_optimized=on, durability=schema_and_data) +go + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/08.2.TV Performance DW - ETL.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/08.2.TV Performance DW - ETL.sql new file mode 100644 index 0000000..583ffb7 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/08.2.TV Performance DW - ETL.sql @@ -0,0 +1,121 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 08.Memory-Optimized Table Variable Performance (DW) - ETL */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +/****************************************************************************/ +/* RECREATE TABLES AFTER EACH EXECUTION USING 08.1 SCRIPT! */ +/****************************************************************************/ + +/*** ETL Process ***/ + +declare + @DT datetime = getDate() + ,@Step1D int, @Step2D int, @Step3D int, @Step1M int, @Step2M int, @Step3M int + +/* On Disk Table */ + +-- Step 1: Staging Table Insert +insert into dw.FactSalesETLDisk + (OrderId,OrderNum,Product,ADate + ,Quantity,UnitPrice,Amount) + select OrderId,OrderNum,Product,ADate + ,Quantity,UnitPrice,Amount + from dbo.InputData; + +/* Optional Index Creation */ +--create index IDX1 on dw.FactSalesETLDisk(Product); + +set @Step1D = datediff(millisecond,@DT,getDate()); set @DT = GetDate(); + +-- Step 2: DimProducts Insert +insert into dw.DimProducts(Product,ProductBin) + select distinct f.Product, f.Product + from dw.FactSalesETLDisk f + where not exists + ( + select * + from dw.DimProducts p + where p.Product = f.Product + ); + +set @Step2D = datediff(millisecond,@DT,getDate()); set @DT = GetDate(); + +-- Step 3: FactSales Insert +insert into dw.FactSales(ADateId,ProductId,OrderId,OrderNum, + Quantity,UnitPrice,Amount) + select d.ADateId,p.ProductId,f.OrderId,f.OrderNum, + f.Quantity,f.UnitPrice,f.Amount + from + dw.FactSalesETLDisk f join dw.DimDates d on + f.ADate = d.ADate + join dw.DimProducts p on + f.Product = p.Product; + +set @Step3D = datediff(millisecond,@DT,getDate()); + +/* Memory-Optimized Table */ +truncate table dw.FactSales; +waitfor delay '00:00:05.000'; + +set @DT = GetDate(); +-- Step 1: Staging Table Insert +insert into dw.FactSalesETLMem + (OrderId,OrderNum,Product,ADate + ,Quantity,UnitPrice,Amount) + select OrderId,OrderNum,Product,ADate + ,Quantity,UnitPrice,Amount + from dbo.InputData; +set @Step1M = datediff(millisecond,@DT,getDate()); set @DT = GetDate(); + +-- Step 2: DimProducts Insert +insert into dw.DimProducts(Product) + select distinct f.Product + from dw.FactSalesETLMem f + where not exists + ( + select * + from dw.DimProducts p + where f.Product = p.ProductBin + ); +set @Step2M = datediff(millisecond,@DT,getDate()); set @DT = GetDate(); + +-- Step 3: FactSales Insert +insert into dw.FactSales(ADateId,ProductId,OrderId,OrderNum, + Quantity,UnitPrice,Amount) + select d.ADateId,p.ProductId,f.OrderId,f.OrderNum, + f.Quantity,f.UnitPrice,f.Amount + from + dw.FactSalesETLMem f join dw.DimDates d on + f.ADate = d.ADate + join dw.DimProducts p on + f.Product = p.ProductBin; +set @Step3M = datediff(millisecond,@DT,getDate()); + +select + 'OnDisk' as [Table] + ,@Step1D as [Staging Table Insert] + ,@Step2D as [DimProducts Insert] + ,@Step3D as [FactSales Insert] + ,@Step1D + @Step2D + @Step3D as [Total Time] +union all +select + 'Memory-Optimized' as [Table] + ,@Step1M as [Staging Table Insert] + ,@Step2M as [DimProducts Insert] + ,@Step3M as [FactSales Insert] + ,@Step1M + @Step2M + @Step3M as [Total Time]; + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/08.3.TV Performance DW - Update.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/08.3.TV Performance DW - Update.sql new file mode 100644 index 0000000..0463229 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/08.3.TV Performance DW - Update.sql @@ -0,0 +1,28 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 08.Memory-Optimized Table Variable Performance (DW) - Update */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +set statistics time on + +update dw.FactSalesETLDisk set Quantity += 1; +update dw.FactSalesETLDisk set OrderNum += '1234567890'; + +update dw.FactSalesETLMem set Quantity += 1; +update dw.FactSalesETLMem set OrderNum += '1234567890'; + +set statistics time off + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/09.Session-Store.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/09.Session-Store.sql new file mode 100644 index 0000000..3a34251 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/09.Session-Store.sql @@ -0,0 +1,199 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 09.Using In-Memory OLTP as the Session- or Object-State Store */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + + +/****************************************************************************/ +/* This script prepares the database schema for SessionStoreDemo demo app */ +/****************************************************************************/ + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'LoadObjectFromStore_Disk') drop proc dbo.LoadObjectFromStore_Disk; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'LoadObjectFromStore') drop proc dbo.LoadObjectFromStore; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'SaveObjectToStore_Row') drop proc dbo.SaveObjectToStore_Row; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'SaveObjectToStore') drop proc dbo.SaveObjectToStore; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'SaveObjectToStore_Disk') drop proc dbo.SaveObjectToStore_Disk; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'SaveObjectToStore_Row_Disk') drop proc dbo.SaveObjectToStore_Row_Disk; +if exists(select * from sys.types t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'tvpObjData') drop type dbo.tvpObjData; +if exists(select * from sys.types t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'tvpObjData_Disk') drop type dbo.tvpObjData_Disk; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'SessionStore') drop table dbo.SessionStore; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'SessionStore_Disk') drop table dbo.SessionStore_Disk; +go + +create table dbo.SessionStore +( + ObjectKey uniqueidentifier not null, + ExpirationTime datetime2(2) not null, + ChunkNum smallint not null, + Data varbinary(8000) not null, + + constraint PK_ObjStore + primary key nonclustered hash (ObjectKey, ChunkNum) + with (bucket_count=1048576), + + index IDX_ObjectKey + nonclustered hash(ObjectKey) + with (bucket_count=1048576) +) +with (memory_optimized = on, durability = schema_only); +go + +create type dbo.tvpObjData as table +( + ChunkNum smallint not null + primary key nonclustered hash + with (bucket_count = 128), + Data varbinary(8000) not null +) +with(memory_optimized=on) +go + +create proc dbo.SaveObjectToStore +( + @ObjectKey uniqueidentifier + ,@ExpirationTime datetime2(2) + ,@ObjData dbo.tvpObjData readonly +) +with native_compilation, schemabinding, exec as owner +as +begin atomic with +( + transaction isolation level = snapshot + ,language = N'English' +) + delete dbo.SessionStore + where ObjectKey = @ObjectKey + + insert into dbo.SessionStore(ObjectKey, ExpirationTime, ChunkNum, Data) + select @ObjectKey, @ExpirationTime, ChunkNum, Data + from @ObjData +end +go + +create proc dbo.SaveObjectToStore_Row +( + @ObjectKey uniqueidentifier + ,@ExpirationTime datetime2(2) + ,@ObjData varbinary(8000) +) +with native_compilation, schemabinding, exec as owner +as +begin atomic with +( + transaction isolation level = snapshot + ,language = N'English' +) + delete dbo.SessionStore + where ObjectKey = @ObjectKey + + insert into dbo.SessionStore(ObjectKey, ExpirationTime, ChunkNum, Data) + values(@ObjectKey, @ExpirationTime, 1, @ObjData) +end +go + +create proc dbo.LoadObjectFromStore +( + @ObjectKey uniqueidentifier not null +) +with native_compilation, schemabinding, exec as owner +as +begin atomic +with +( + transaction isolation level = snapshot + ,language = N'English' +) + select t.Data + from dbo.SessionStore t + where t.ObjectKey = @ObjectKey and ExpirationTime >= sysutcdatetime() + order by t.ChunkNum +end +go + + + +create table dbo.SessionStore_Disk +( + ObjectKey uniqueidentifier not null, + ExpirationTime datetime2(2) not null, + ChunkNum smallint not null, + Data varbinary(8000) not null, + + constraint PK_ObjStore_Disk + primary key clustered(ObjectKey, ChunkNum) +) +go + +create type dbo.tvpObjData_Disk as table +( + ChunkNum smallint not null primary key, + Data varbinary(8000) not null +) +go + +create proc dbo.SaveObjectToStore_Disk +( + @ObjectKey uniqueidentifier + ,@ExpirationTime datetime2(2) + ,@ObjData dbo.tvpObjData_Disk readonly +) +as +begin + set nocount on + set xact_abort on + + begin tran + delete dbo.SessionStore_Disk + where ObjectKey = @ObjectKey + + insert into dbo.SessionStore_Disk(ObjectKey, ExpirationTime, ChunkNum, Data) + select @ObjectKey, @ExpirationTime, ChunkNum, Data + from @ObjData + commit +end +go + +create proc dbo.SaveObjectToStore_Row_Disk +( + @ObjectKey uniqueidentifier + ,@ExpirationTime datetime2(2) + ,@ObjData varbinary(8000) +) +as +begin + set nocount on + set xact_abort on + + begin tran + delete dbo.SessionStore_Disk + where ObjectKey = @ObjectKey + + insert into dbo.SessionStore_Disk(ObjectKey, ExpirationTime, ChunkNum, Data) + values(@ObjectKey, @ExpirationTime, 1, @ObjData) + commit +end +go + +create proc dbo.LoadObjectFromStore_Disk +( + @ObjectKey uniqueidentifier +) +as + select t.Data + from dbo.SessionStore_Disk t + where t.ObjectKey = @ObjectKey and ExpirationTime >= sysutcdatetime() + order by t.ChunkNum +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/10.Data Partitioning.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/10.Data Partitioning.sql new file mode 100644 index 0000000..1c2ca02 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/10.Data Partitioning.sql @@ -0,0 +1,155 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 10.Example of Data Partitioning */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'InsertOrderLineItems') drop proc dbo.InsertOrderLineItems; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'DeleteOrder') drop proc dbo.DeleteOrder; +if exists(select * from sys.views v join sys.schemas s on v.schema_id = s.schema_id where s.name = 'dbo' and v.name = 'Orders') drop view dbo.Orders; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'Orders') drop table dbo.Orders; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'OldOrders') drop table dbo.OldOrders; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'LastYearOrders') drop table dbo.LastYearOrders; +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'RecentOrders') drop table dbo.RecentOrders; +if exists(select * from sys.partition_schemes where name = 'psOldOrders') drop partition scheme psOldOrders; +if exists(select * from sys.partition_schemes where name = 'psLastYearOrders') drop partition scheme psLastYearOrders; +if exists(select * from sys.partition_functions where name = 'pfOldOrders') drop partition function pfOldOrders; +if exists(select * from sys.partition_functions where name = 'pfLastYearOrders') drop partition function pfLastYearOrders; +go + +-- Storing Orders with OrderDate >= 2015-01-01 +create table dbo.RecentOrders +( + OrderId int not null identity(1,1), + OrderDate datetime2(0) not null, + OrderNum varchar(32) + collate Latin1_General_100_BIN2 not null, + CustomerId int not null, + Amount money not null, + /* Other columns */ + constraint PK_RecentOrders + primary key nonclustered hash(OrderId) + with (bucket_count=1048576), + + index IDX_RecentOrders_CustomerId + nonclustered(CustomerId) +) +with (memory_optimized=on, durability=schema_and_data) +go + +create partition function pfLastYearOrders(datetime2(0)) +as range right for values +('2014-04-01','2014-07-01','2014-10-01','2015-01-01') +go + + +create partition scheme psLastYearOrders +as partition pfLastYearOrders +all to ([primary]) +go + +create table dbo.LastYearOrders +( + OrderId int not null, + OrderDate datetime2(0) not null, + OrderNum varchar(32) + collate Latin1_General_100_BIN2 not null, + CustomerId int not null, + Amount money not null, + /* Other columns */ + -- We have to include OrderDate to PK + -- due to partitioning + constraint PK_LastYearOrders + primary key clustered(OrderDate,OrderId) + with (data_compression=row) + on psLastYearOrders(OrderDate), + + constraint CHK_LastYearOrders + check + ( + OrderDate >= '2014-01-01' and + OrderDate < '2015-01-01' + ) +); + +create nonclustered index IDX_LastYearOrders_CustomerId +on dbo.LastYearOrders(CustomerID) +with (data_compression=row) +on psLastYearOrders(OrderDate); +go + + +create partition function pfOldOrders(datetime2(0)) +as range right for values +( /* Old intervals */ + '2012-10-01','2013-01-01','2013-04-01' + ,'2013-07-01','2013-10-01','2014-01-01' +) +go + + +create partition scheme psOldOrders +as partition pfOldOrders +all to ([primary]) +go + +create table dbo.OldOrders +( + OrderId int not null, + OrderDate datetime2(0) not null, + OrderNum varchar(32) + collate Latin1_General_100_BIN2 not null, + CustomerId int not null, + Amount money not null, + /* Other columns */ + constraint CHK_OldOrders + check(OrderDate < '2014-01-01') +) +on psOldOrders(OrderDate); + +create clustered columnstore index CCI_OldOrders +on dbo.OldOrders +with (data_compression=columnstore_Archive) +on psOldOrders(OrderDate); +go + +create view dbo.Orders(OrderId,OrderDate, + OrderNum,CustomerId,Amount) +as + select OrderId,OrderDate,OrderNum,CustomerId,Amount + from dbo.RecentOrders + where OrderDate >= '2015-01-01' + + union all + + select OrderId,OrderDate,OrderNum,CustomerId,Amount + from dbo.LastYearOrders + + union all + + select OrderId,OrderDate,OrderNum,CustomerId,Amount + from dbo.OldOrders +go + +select top 10 + CustomerId, sum(Amount) as [TotalSales] +from dbo.Orders +where + OrderDate >='2013-07-01' and + OrderDate < '2014-07-01' +group by + CustomerId +order by + sum(Amount) desc diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/11.Chapter 11 (Untilizing In-Memory OLTP).ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/11.Chapter 11 (Untilizing In-Memory OLTP).ssmssqlproj new file mode 100644 index 0000000..5476047 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/11.Chapter 11 (Untilizing In-Memory OLTP).ssmssqlproj @@ -0,0 +1,99 @@ + + + + + + + + + + + + + 01.Vertical Partitioning.sql + + + + + + 02.Splitting Data.sql + + + + + + 03.1.Uniqueness Support.sql + + + + + + 03.2.Uniqueness Support.sql + + + + + + 04.Referential Integrity.sql + + + + + + 05.Binary Collation.sql + + + + + + 06.TVP.sql + + + + + + 07.TV Performance OLTP.sql + + + + + + 08.1.TV Performance DW - Create.sql + + + + + + 08.2.TV Performance DW - ETL.sql + + + + + + 08.3.TV Performance DW - Update.sql + + + + + + 09.Session-Store.sql + + + + + + 10.Data Partitioning.sql + + + + + + 11.Natively Compiled SPs.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/11.Natively Compiled SPs.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/11.Natively Compiled SPs.sql new file mode 100644 index 0000000..1fe8b16 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/11.Natively Compiled SPs.sql @@ -0,0 +1,311 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Chapter 11: Utilizing In-Memory OLTP */ +/* 11.Evaluating Performance of Natively Compiled SPs */ +/****************************************************************************/ + +set nocount on +go + +use InMemoryOLTP2014 +go + +if object_id(N'dbo.CalcDistance','FN') is not null drop function dbo.CalcDistance; +if object_id(N'dbo.CalcDistanceInline','IF') is not null drop function dbo.CalcDistanceInline; +if object_id(N'dbo.CalcDistanceCLR','FS') is not null drop function dbo.CalcDistanceCLR; +if exists(select * from sys.assemblies where name = 'InMemOLTPBoxCLR') drop assembly InMemOLTPBoxCLR; +if exists(select * from sys.procedures p join sys.schemas s on p.schema_id = s.schema_id where s.name = 'dbo' and p.name = 'CalcDistanceInMem') drop proc dbo.CalcDistanceInMem; +go + +create function dbo.CalcDistance +( + @LoopCnt int + ,@FromLat decimal(9,6) + ,@FromLon decimal(9,6) + ,@ToLat decimal(9,6) + ,@ToLon decimal(9,6) +) +returns float +with schemabinding +as +begin + declare + @Dist float + ,@Loop int = 0 + ,@FromLatR float + ,@FromLonR float + ,@ToLatR float + ,@ToLonR float + + while @Loop < @LoopCnt + begin + select + @FromLatR = radians(@FromLat) + ,@FromLonR = radians(@FromLon) + ,@ToLatR = radians(@ToLat) + ,@ToLonR = radians(@ToLon) + + set @Dist = + 2 * asin( + sqrt( + power(sin( (@FromLatR - @ToLatR) / 2.), 2) + + ( + cos(@FromLatR) * + cos(@ToLatR) * + power(sin((@FromLonR - @ToLonR) / 2.0), 2) + ) + ) + ) * 20001600. / pi() + select @Loop += 1; + end + return @Dist +end; +go + +create proc dbo.CalcDistanceInMem +( + @LoopCnt int + ,@FromLat decimal(9,6) + ,@FromLon decimal(9,6) + ,@ToLat decimal(9,6) + ,@ToLon decimal(9,6) + ,@Dist float output +) +with native_compilation, schemabinding, execute as owner +as +begin atomic with +( + transaction isolation level = snapshot + ,language = N'English' +) + declare + @Loop int = 0 + ,@FromLatR float + ,@FromLonR float + ,@ToLatR float + ,@ToLonR float + + while @Loop < @LoopCnt + begin + select + @FromLatR = radians(@FromLat) + ,@FromLonR = radians(@FromLon) + ,@ToLatR = radians(@ToLat) + ,@ToLonR = radians(@ToLon) + + set @Dist = + 2 * asin( + sqrt( + power(sin( (@FromLatR - @ToLatR) / 2.), 2) + + ( + cos(@FromLatR) * + cos(@ToLatR) * + power(sin((@FromLonR - @ToLonR) / 2.0), 2) + ) + ) + ) * 20001600. / pi() + select @Loop += 1; + end +end; +go + +/* One call - multiple loops inside */ +declare + @Result float + ,@LoopCnt int = 10000 + ,@DT datetime + +select @DT = getdate(); +select @Result = dbo.CalcDistance(@LoopCnt,28,-82,29,-83); +select datediff(millisecond,@DT,GetDate()) as [T-SQL Function]; +go + +declare + @Result float + ,@LoopCnt int = 10000 + ,@DT datetime + +select @DT = getdate(); +exec dbo.CalcDistanceInMem @LoopCnt,28,-82,29,-83, @Result output +select datediff(millisecond,@DT,GetDate()) as [Natively Compiled Proc]; +go + +/* Multiple Calls in the Loop */ +declare + @Result float + ,@LoopCnt int = 10000 + ,@DT datetime + ,@I int = 0 + +select @DT = getdate(); +while @I < @LoopCnt +begin + select @Result = dbo.CalcDistance(1,28,-82,29,-83); + select @I += 1; +end +select datediff(millisecond,@DT,GetDate()) as [T-SQL Function]; +go + +declare + @Result float + ,@LoopCnt int = 10000 + ,@DT datetime + ,@I int = 0 + +select @DT = getdate(); +while @I < @LoopCnt +begin + exec dbo.CalcDistanceInMem 1,28,-82,29,-83, @Result output + select @I += 1; +end +select datediff(millisecond,@DT,GetDate()) as [Natively Compiled Proc]; +go + + +/* Let's check performance of Inline Function */ +create function dbo.CalcDistanceInline +( + @FromLat decimal(9,6) + ,@FromLon decimal(9,6) + ,@ToLat decimal(9,6) + ,@ToLon decimal(9,6) +) +returns table +as +return +( + with Rads(FromLatR, FromLonR, ToLatR, ToLonR) + as + ( + select + radians(@FromLat), radians(@FromLon), + radians(@ToLat), radians(@ToLon) + ) + select + 2 * asin( + sqrt( + power(sin((FromLatR - ToLatR) / 2.), 2) + + ( + cos(FromLatR) * + cos(ToLatR) * + power(sin((FromLonR - ToLonR) / 2.0),2) + ) + ) + ) * 20001600. / pi() as Distance + from Rads +); +go + +declare + @Result float + ,@LoopCnt int = 10000 + ,@DT datetime + ,@I int = 0 + +select @DT = getdate(); +while @I < @LoopCnt +begin + exec dbo.CalcDistanceInMem 1,28,-82,29,-83, @Result output + select @I += 1; +end +select datediff(millisecond,@DT,GetDate()) as [Natively Compiled Proc]; +go + + +declare + @Result float + ,@LoopCnt int = 10000 + ,@DT datetime + ,@I int = 0 + +select @DT = getdate(); +while @I < @LoopCnt +begin + select @Result = Distance + from dbo.CalcDistanceInline(28,-82,29,-83); + select @I += 1; +end +select datediff(millisecond,@DT,GetDate()) as [Inline Function]; +go + + +create assembly [InMemOLTPBoxCLR] +authorization [dbo] +from 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C0103007AEAE1550000000000000000E00002210B010B00000A00000006000000000000DE2900000020000000400000000000100020000000020000040000000000000004000000000000000080000000020000000000000300408500001000001000000000100000100000000000001000000000000000000000008C2900004F00000000400000C002000000000000000000000000000000000000006000000C000000542800001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E74657874000000E409000000200000000A000000020000000000000000000000000000200000602E72737263000000C00200000040000000040000000C0000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000001000000000000000000000000000004000004200000000000000000000000000000000C02900000000000048000000020005002022000034060000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013300200AE0000000100001100166A0A0F00280500000A2D230F01280500000A2D1A0F00280600000A1632100F00280600000A1F5DFE0216FE012B011600130611062D097E0700000A13052B6A160D2B4C000F00280600000A17FE0216FE01130611062D3000176A0A166A0B1813042B1000060C0607580A080B0011041758130411040F00280600000AFE04130611062DDF002B03166A0A000917580D090F01280600000AFE04130611062DA406730800000A13052B0011052A000013300500FF0000000200001100230000000000000000130416130538C90000000023399D52A246DF913F0F01280900000A5A0A23399D52A246DF913F0F02280900000A5A0B23399D52A246DF913F0F03280900000A5A0C23399D52A246DF913F0F04280900000A5A0D2300000000000000400608592300000000000000405B280A00000A230000000000000040280B00000A06280C00000A08280C00000A5A0709592300000000000000405B280A00000A230000000000000040280B00000A5A58280D00000A280E00000A5A2300000000341373415A23182D4454FB2109405B13040011051758130511050F00280600000AFE04130711073A23FFFFFF1104730F00000A13062B0011062A1E02281000000A2A0042534A4201000100000000000C00000076322E302E35303732370000000005006C000000B8010000237E000024020000E001000023537472696E6773000000000404000008000000235553000C0400001000000023475549440000001C0400001802000023426C6F620000000000000002000001471502000900000000FA253300160000010000000A000000020000000300000007000000100000000500000002000000010000000200000000000A00010000000000060043003C000A006B0056000A00740056000A008E0056000600E700D4001700FB00000006002A010A0106004A010A010A00930178010600C2013C000000000001000000000001000100010010001E00000005000100010050200000000096007D000A0001000C210000000096009800130003001722000000008618A8002200080000000100AE0000000200B00000000100B00000000200B80000000300C00000000400C80000000500CE002900A80026003900A8002C004100A80022004900A80022001900A801EE001900B301F2001100BD01F6001100A800FA002100B301C7015100C701CB015100CB01D0015100CF01CB015100D301CB015100D801CB012100A800D6010900A80022002000230031002E000B00E7012E001300F0012E001B00F901400023000A01FF00DB0104800000000000000000000000000000000068010000020000000000000000000000010033000000000002000000000000000000000001004A00000000000000003C4D6F64756C653E00496E4D656D4F4C5450426F78434C522E646C6C0055736572446566696E656446756E6374696F6E73006D73636F726C69620053797374656D004F626A6563740053797374656D2E446174610053797374656D2E446174612E53716C54797065730053716C496E7436340053716C496E7433320043616C634669626F6E61636369434C520053716C446F75626C650043616C6344697374616E6365434C52002E63746F72004E006C6F6F70436E740066726F6D4C61740066726F6D4C6F6E00746F4C617400746F4C6F6E0053797374656D2E446961676E6F73746963730044656275676761626C6541747472696275746500446562756767696E674D6F6465730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C69747941747472696275746500496E4D656D4F4C5450426F78434C52004D6963726F736F66742E53716C5365727665722E5365727665720053716C46756E6374696F6E417474726962757465006765745F49734E756C6C006765745F56616C7565004E756C6C004D6174680053696E00506F7700436F730053717274004173696E00000000000320000000000054FCAFBBB51DD240ABDAA1B0D8FDF0790008B77A5C561934E0890800021109110D110D0E00051111110D111111111111111103200001052001011119042001010880BB0100030054020F497344657465726D696E6973746963015402094973507265636973650154557F4D6963726F736F66742E53716C5365727665722E5365727665722E53797374656D446174614163636573734B696E642C2053797374656D2E446174612C2056657273696F6E3D322E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038391053797374656D4461746141636365737300000000032000020320000803061109042001010A0A07070A0A0A080811090280BB0100030054020F497344657465726D696E6973746963015402094973507265636973650054557F4D6963726F736F66742E53716C5365727665722E5365727665722E53797374656D446174614163636573734B696E642C2053797374656D2E446174612C2056657273696F6E3D322E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038391053797374656D44617461416363657373000000000320000D0400010D0D0500020D0D0D042001010D0B07080D0D0D0D0D081111020801000701000000000801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301000000007AEAE15500000000020000001C01000070280000700A0000525344531ABC26750F384947BE11DC9A60B2468702000000653A5C576F726B5C576F726B5C56535C496E4D656D4F4C5450426F785C434C525C6F626A5C44656275675C496E4D656D4F4C5450426F78434C522E706462000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B42900000000000000000000CE290000002000000000000000000000000000000000000000000000C0290000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF25002000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000001800008000000000000000000000000000000100010000003000008000000000000000000000000000000100000000004800000058400000640200000000000000000000640234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000000000000000000000000000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004C4010000010053007400720069006E006700460069006C00650049006E0066006F000000A001000001003000300030003000300034006200300000002C0002000100460069006C0065004400650073006300720069007000740069006F006E000000000020000000300008000100460069006C006500560065007200730069006F006E000000000030002E0030002E0030002E003000000048001400010049006E007400650072006E0061006C004E0061006D006500000049006E004D0065006D004F004C005400500042006F00780043004C0052002E0064006C006C0000002800020001004C006500670061006C0043006F0070007900720069006700680074000000200000005000140001004F0072006900670069006E0061006C00460069006C0065006E0061006D006500000049006E004D0065006D004F004C005400500042006F00780043004C0052002E0064006C006C000000340008000100500072006F006400750063007400560065007200730069006F006E00000030002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000030002E0030002E0030002E0030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C000000E03900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000; +go + +create function [dbo].[CalcDistanceCLR] +(@loopCnt int, @fromLat float, @fromLon float, @toLat float, @toLon float) +returns float +as + external name [InMemOLTPBoxCLR].[UserDefinedFunctions].[CalcDistanceCLR]; +go + +/**************************************************************************** +[Microsoft.SqlServer.Server.SqlFunction( + IsDeterministic = true, IsPrecise = false, + SystemDataAccess = SystemDataAccessKind.None)] +public static SqlDouble CalcDistanceCLR +( + SqlInt32 loopCnt, + SqlDouble fromLat, SqlDouble fromLon, + SqlDouble toLat, SqlDouble toLon +) +{ + double fromLatR, fromLonR, toLatR, toLonR, result = 0; + + for (int i = 0; i < loopCnt.Value; i++) + { + fromLatR = Math.PI / 180 * fromLat.Value; + fromLonR = Math.PI / 180 * fromLon.Value; + toLatR = Math.PI / 180 * toLat.Value; + toLonR = Math.PI / 180 * toLon.Value; + result = + 2 * Math.Asin( + Math.Sqrt( + Math.Pow(Math.Sin((fromLatR - toLatR) / 2.0), 2) + + ( + Math.Cos(fromLatR) * Math.Cos(toLatR) * + Math.Pow(Math.Sin((fromLonR - toLonR) / 2.0), 2) + ) + )) * 20001600.0 / Math.PI; + }; + return new SqlDouble(result); +} +****************************************************************************/ + +declare + @Result float + ,@LoopCnt int = 10000 + ,@DT datetime + ,@I int = 0 + +select @DT = getdate(); +while @I < @LoopCnt +begin + exec dbo.CalcDistanceInMem 1,28,-82,29,-83, @Result output + select @I += 1; +end +select datediff(millisecond,@DT,GetDate()) as [Natively Compiled Proc]; +go + +declare + @Result float + ,@LoopCnt int = 10000 + ,@DT datetime + ,@I int = 0 + +select @DT = getdate(); +while @I < @LoopCnt +begin + select @Result = dbo.CalcDistanceCLR(1,28,-82,29,-83) + select @I += 1; +end +select datediff(millisecond,@DT,GetDate()) as [CLR Proc]; +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/FactSales.fmt b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/FactSales.fmt new file mode 100644 index 0000000..b776970 Binary files /dev/null and b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/FactSales.fmt differ diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/createtable.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/createtable.sql new file mode 100644 index 0000000..76a5c54 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/createtable.sql @@ -0,0 +1,14 @@ +if exists(select * from sys.tables t join sys.schemas s on t.schema_id = s.schema_id where s.name = 'dbo' and t.name = 'InputData') drop table dbo.InputData; +go + +create table dbo.InputData +( + ADate date not null, + Product nvarchar(40) not null, + OrderId int not null, + OrderNum varchar(43) not null, + Quantity decimal(9,3) not null, + UnitPrice money not null, + Amount money not null +) +go \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/factsales.dat b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/factsales.dat new file mode 100644 index 0000000..f78ba17 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/factsales.dat @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c1819a615149913d3ad8c3633aeb7cf31fa4033ea071e238b53348cf11c6b04 +size 132149621 diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/import.cmd b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/import.cmd new file mode 100644 index 0000000..8efc5e0 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/11.Chapter 11 (Untilizing In-Memory OLTP)/ETL/import.cmd @@ -0,0 +1,3 @@ +sqlcmd -S "." -E -i createTable.sql -d InMemoryOLTP2014 +bcp InMemoryOLTP2014.dbo.InputData in "factsales.dat" -T -f "FactSales.fmt" -b 50000 -S "." +pause diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/14.Appendix C (Analyzing the States of CFPs)/01.DB Creation.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/14.Appendix C (Analyzing the States of CFPs)/01.DB Creation.sql new file mode 100644 index 0000000..b73e18a --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/14.Appendix C (Analyzing the States of CFPs)/01.DB Creation.sql @@ -0,0 +1,84 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Appendix C: Analyzing the States of Checkpoint File Pairs */ +/* 01.DB Creation */ +/****************************************************************************/ + +set noexec off +go + +use master +go + +if convert(int, + left( + convert(nvarchar(128), serverproperty('ProductVersion')), + charindex('.',convert(nvarchar(128), serverproperty('ProductVersion'))) - 1 + ) + ) < 12 +begin + raiserror('You should have SQL Server 2014 to execute this script',16,1) with nowait + set noexec on +end +go + +if convert(int, serverproperty('EngineEdition')) != 3 or charindex('X64',@@Version) = 0 +begin + raiserror('That script requires 64-Bit Enterprise Edition of SQL Server to run',16,1) + set noexec on +end +go + +if exists +( + select * from sys.databases where name = 'InMemoryOLTP2014_AppendixC' +) +begin + raiserror('Database InMemoryOLTP2014_AppendixC already created',16,1) + set noexec on +end +go + + + +declare + @dataPath nvarchar(512) = convert(nvarchar(512),serverproperty('InstanceDefaultDataPath')) + ,@logPath nvarchar(512) = convert(nvarchar(512),serverproperty('InstanceDefaultLogPath')) + +/*** REPLACE IF YOU WANT TO STORE IN-MEMORY OLTP FILES IN THE DIFFERENT PLACE ***/ +declare + @HKPath nvarchar(512) = @dataPath + 'InMemoryOLTP2014_AppendixC_HKData' + +declare + @SQL nvarchar(max) + +select @SQL = +N'create database [InMemoryOLTP2014_AppendixC] on +primary (name=N''InMemoryOLTP2014_AppendixC'', filename=N''' + @dataPath + N'InMemoryOLTP2014_AppendixC.mdf'', size=102400KB, filegrowth = 102400KB), +filegroup [HKData] contains memory_optimized_data (name=N''InMemoryOLTP2014_AppendixC_HekatonData'', filename=N''' + @HKPath + N''') +log on (name=N''InMemoryOLTP2014_AppendixC_log'', filename=N''' + @logPath + N'InMemoryOLTP2014_AppendixC.ldf'', size=256000KB, filegrowth = 256000KB); + +alter database [InMemoryOLTP2014_AppendixC] set recovery full;' + +raiserror('Creating database InMemoryOLTP2014_AppendixC',0,1) with nowait +raiserror('Data Path: %s',0,1,@dataPath) with nowait +raiserror('Log Path: %s',0,1,@logPath) with nowait +raiserror('Hekaton Folder: %s',0,1,@HKPath) with nowait +raiserror('Statement:',0,1) with nowait +raiserror(@sql,0,1) with nowait + +exec sp_executesql @sql +go + +-- Start backup chain +backup database InMemoryOLTP2014_AppendixC +to disk = N'InMemoryOLTP2014_AppendixC.bak' +with noformat, init, name = 'InMemoryOLTP2014_AppendixC - Full', compression +go + diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/14.Appendix C (Analyzing the States of CFPs)/02.Analyzing States.sql b/SQL/Expert SQL Server In-Memory OLTP (2014)/14.Appendix C (Analyzing the States of CFPs)/02.Analyzing States.sql new file mode 100644 index 0000000..c76d57d --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/14.Appendix C (Analyzing the States of CFPs)/02.Analyzing States.sql @@ -0,0 +1,369 @@ +/****************************************************************************/ +/* Expert SQL Server In-Memory OLTP */ +/* APress. 1st Edition. ISBN-13:978-1484211373 ISBN-10:1484211375 */ +/* */ +/* Written by Dmitri V. Korotkevitch */ +/* http://aboutsqlserver.com */ +/* dk@aboutsqlserver.com */ +/****************************************************************************/ +/* Appendix C: Analyzing the States of Checkpoint File Pairs */ +/* 02.Analyzing CFPs states */ +/****************************************************************************/ + +set noexec off +go + +set nocount on +go + +use InMemoryOLTP2014_AppendixC +go + +if exists(select * from sys.dm_db_xtp_checkpoint_files) +begin + raiserror('Please recreate the database using 01.DB Creation script',16,1) with nowait + set noexec on +end +go + +/* Disabling automatic merge. DO NOT RUN IN PRODUCTION! */ +dbcc traceon(9851,-1) +go + + + +-- Empty result set - there is no memory-optimized objects in the database +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count + ,relative_file_path +from sys.dm_db_xtp_checkpoint_files +order by + state, file_type +go + +create table dbo.HKData +( + ID int not null, + Placeholder char(8000) not null, + + constraint PK_HKData + primary key nonclustered hash(ID) + with (bucket_count=10000), +) +with (memory_optimized=on, durability=schema_and_data) +go + +-- PRECREATED/UNDER CONSTRUCTION FILES +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count + ,relative_file_path +from sys.dm_db_xtp_checkpoint_files +order by + state, file_type +go + +-- Populating table with the data +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N4 as t2) -- 65,536 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N5) +insert into dbo.HKData(Id, Placeholder) + select Id, Replicate('0',8000) + from ids + where Id <= 1000; +go + +-- UNDER CONSTRUCTION FILES +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count + ,relative_file_path +from + sys.dm_db_xtp_checkpoint_files +where + state_desc <> 'PRECREATED' +order by + state, file_type +go + +checkpoint +go + +-- UNDER CONSTRUCTION becomes ACTIVE +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count + ,relative_file_path +from + sys.dm_db_xtp_checkpoint_files +where + state_desc <> 'PRECREATED' +order by + state, file_type +go + +-- Adding more data +;with N1(C) as (select 0 union all select 0) -- 2 rows +,N2(C) as (select 0 from N1 as t1 cross join N1 as t2) -- 4 rows +,N3(C) as (select 0 from N2 as t1 cross join N2 as t2) -- 16 rows +,N4(C) as (select 0 from N3 as t1 cross join N3 as t2) -- 256 rows +,N5(C) as (select 0 from N4 as t1 cross join N4 as t2) -- 65,536 rows +,Ids(Id) as (select row_number() over (order by (select null)) from N5) +insert into dbo.HKData(Id, Placeholder) + select 1000 + Id, Replicate('0',8000) + from ids + where Id <= 1000; +go + +-- ACTIVE + UNDER CONSTRUCTION FILES +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count + ,relative_file_path +from + sys.dm_db_xtp_checkpoint_files +where + state_desc <> 'PRECREATED' +order by + state, file_type +go + +checkpoint +go + +-- UNDER CONSTRUCTION becomes ACTIVE +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count + ,relative_file_path +from + sys.dm_db_xtp_checkpoint_files +where + state_desc <> 'PRECREATED' +order by + state, file_type +go + + +-- Deleting 66.7% of the data +delete from dbo.HKData +where ID % 3 <> 0; +go + +select + data.checkpoint_file_id + ,data.state_desc + ,data.lower_bound_tsn + ,data.upper_bound_tsn + ,data.file_size_in_bytes + ,data.file_size_used_in_bytes + ,data.inserted_row_count + ,delta.deleted_row_count + ,convert(decimal(5,2),100. - 100. * delta.deleted_row_count / data.inserted_row_count) + as [% Full] +from + sys.dm_db_xtp_checkpoint_files data join + sys.dm_db_xtp_checkpoint_files delta on + data.checkpoint_pair_file_id = delta.checkpoint_file_id +where + data.file_type_desc = 'DATA' and + data.state_desc <> 'PRECREATED' +go + + +-- Forcing manual merge and checking merge request status +-- Make sure to specify correct upper and lower bounds for the merge +exec sys.sp_xtp_merge_checkpoint_files + @database_name = 'InMemoryOLTP2014_AppendixC' + ,@transaction_lower_bound = 1 + ,@transaction_upper_bound = 8; + +select + request_state_desc + ,destination_file_id + ,lower_bound_tsn + ,upper_bound_tsn + ,source0_file_id + ,source1_file_id +from sys.dm_db_xtp_merge_requests; +go + +-- Wait several seconds + +-- ACTIVE + MERGE TARGET +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count + ,relative_file_path +from + sys.dm_db_xtp_checkpoint_files +where + state_desc <> 'PRECREATED' +order by + state, file_type +go + +checkpoint +go + +-- MERGED SOURCE +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count + ,relative_file_path +from + sys.dm_db_xtp_checkpoint_files +where + state_desc <> 'PRECREATED' +order by + state, file_type +go + +checkpoint +go + +-- REQUIRED FOR BACKUP/HA +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count + ,relative_file_path +from + sys.dm_db_xtp_checkpoint_files +where + state_desc <> 'PRECREATED' +order by + state, file_type +go + +-- Backing up log. There is the chance that you'll need to do +-- Backup/Checkpoint multiple times to force CFPs to GC state +backup log InMemoryOLTP2014_AppendixC +to disk = N'InMemoryOLTP2014_AppendixC.bak' +with noformat, noinit, name = 'AppendixD - Log', compression +go + +checkpoint +go + +-- IN TRANSITION TO TOMBSTONE +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count + ,relative_file_path +from + sys.dm_db_xtp_checkpoint_files +where + state_desc <> 'PRECREATED' +order by + state, file_type +go + +exec sys.sp_xtp_checkpoint_force_garbage_collection +go + +select + checkpoint_file_id + ,checkpoint_pair_file_id + ,file_type_desc + ,state_desc + ,lower_bound_tsn + ,upper_bound_tsn + ,file_size_in_bytes + ,file_size_used_in_bytes + ,inserted_row_count + ,deleted_row_count +from + sys.dm_db_xtp_checkpoint_files +where + state_desc <> 'PRECREATED' +order by + state, file_type +go + +-- Make sure to re-enable automatic merge! +dbcc traceoff(9851,-1) +go diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/14.Appendix C (Analyzing the States of CFPs)/14.Appendix C (Analyzing the States of CFPs).ssmssqlproj b/SQL/Expert SQL Server In-Memory OLTP (2014)/14.Appendix C (Analyzing the States of CFPs)/14.Appendix C (Analyzing the States of CFPs).ssmssqlproj new file mode 100644 index 0000000..70da959 --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/14.Appendix C (Analyzing the States of CFPs)/14.Appendix C (Analyzing the States of CFPs).ssmssqlproj @@ -0,0 +1,27 @@ + + + + + + + + + + + + + 01.DB Creation.sql + + + + + + 02.Analyzing States.sql + + + + + + + + \ No newline at end of file diff --git a/SQL/Expert SQL Server In-Memory OLTP (2014)/Expert SQL Server In-Memory OLTP (2014).ssmssln b/SQL/Expert SQL Server In-Memory OLTP (2014)/Expert SQL Server In-Memory OLTP (2014).ssmssln new file mode 100644 index 0000000..4e0eeaf --- /dev/null +++ b/SQL/Expert SQL Server In-Memory OLTP (2014)/Expert SQL Server In-Memory OLTP (2014).ssmssln @@ -0,0 +1,47 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# SQL Server Management Studio Solution File, Format Version 12.00 +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "00.Init", "00.Init\00.Init.ssmssqlproj", "{3CA93053-1F61-4009-A03D-6C8D8E16A3AF}" +EndProject +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "02.Chapter 02 (In-Memory OLTP Objects)", "02.Chapter 02 (In-Memory OLTP Objects)\02.Chapter 02 (In-Memory OLTP Objects).ssmssqlproj", "{19349805-E689-40EB-9851-FF39BD7464B5}" +EndProject +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "04.Chapter 04 (Hash Indexes)", "04.Chapter 04 (Hash Indexes)\04.Chapter 04 (Hash Indexes).ssmssqlproj", "{C8C2C436-CEAA-4D1B-A6F4-92031B903256}" +EndProject +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "05.Chapter 05 (Nonclustered Indexes)", "05.Chapter 05 (Nonclustered Indexes)\05.Chapter 05 (Nonclustered Indexes).ssmssqlproj", "{983D3631-73F5-440A-A740-1D155F222537}" +EndProject +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "06.Chapter 06 (In-Memory OLTP Programmability)", "06.Chapter 06 (In-Memory OLTP Programmability)\06.Chapter 06 (In-Memory OLTP Programmability).ssmssqlproj", "{F719F1D8-47F1-4EC2-B068-F309820250AE}" +EndProject +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "07.Chapter 07 (In-Memory OLTP Concurrency Model)", "07.Chapter 07 (In-Memory OLTP Concurrency Model)\07.Chapter 07 (In-Memory OLTP Concurrency Model).ssmssqlproj", "{6E3F803A-B072-4EA0-84A8-7D6A8EACF1FE}" +EndProject +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "08.Chapter 08 (Data Storage, Logging and Recovery)", "08.Chapter 08 (Data Storage, Logging and Recovery)\08.Chapter 08 (Data Storage, Logging and Recovery).ssmssqlproj", "{701C411D-1A66-4242-ADAA-3EC2F420A254}" +EndProject +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "09.Chapter 09 (Garbage Collection)", "09.Chapter 09 (Garbage Collection)\09.Chapter 09 (Garbage Collection).ssmssqlproj", "{3F536680-93C3-4F33-87DB-FFE05E10C7EE}" +EndProject +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "10.Chapter 10 (Deployment and Management)", "10.Chapter 10 (Deployment and Management)\10.Chapter 10 (Deployment and Management).ssmssqlproj", "{D422B378-3491-4175-B162-7F841EA3ACB8}" +EndProject +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "11.Chapter 11 (Untilizing In-Memory OLTP)", "11.Chapter 11 (Untilizing In-Memory OLTP)\11.Chapter 11 (Untilizing In-Memory OLTP).ssmssqlproj", "{BCF36AF4-3605-47E1-8232-2426F87EF083}" +EndProject +Project("{4F2E2C19-372F-40D8-9FA7-9D2138C6997A}") = "14.Appendix C (Analyzing the States of CFPs)", "14.Appendix C (Analyzing the States of CFPs)\14.Appendix C (Analyzing the States of CFPs).ssmssqlproj", "{8D22ED55-DDF6-4C45-9945-1B374BE49EEE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Default|Default = Default|Default + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3CA93053-1F61-4009-A03D-6C8D8E16A3AF}.Default|Default.ActiveCfg = Default + {163D206D-FE8F-4E40-AD8C-40F619898F68}.Default|Default.ActiveCfg = Default + {19349805-E689-40EB-9851-FF39BD7464B5}.Default|Default.ActiveCfg = Default + {C8C2C436-CEAA-4D1B-A6F4-92031B903256}.Default|Default.ActiveCfg = Default + {983D3631-73F5-440A-A740-1D155F222537}.Default|Default.ActiveCfg = Default + {F719F1D8-47F1-4EC2-B068-F309820250AE}.Default|Default.ActiveCfg = Default + {6E3F803A-B072-4EA0-84A8-7D6A8EACF1FE}.Default|Default.ActiveCfg = Default + {701C411D-1A66-4242-ADAA-3EC2F420A254}.Default|Default.ActiveCfg = Default + {3F536680-93C3-4F33-87DB-FFE05E10C7EE}.Default|Default.ActiveCfg = Default + {D422B378-3491-4175-B162-7F841EA3ACB8}.Default|Default.ActiveCfg = Default + {BCF36AF4-3605-47E1-8232-2426F87EF083}.Default|Default.ActiveCfg = Default + {8D22ED55-DDF6-4C45-9945-1B374BE49EEE}.Default|Default.ActiveCfg = Default + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/contributing.md b/contributing.md new file mode 100644 index 0000000..f6005ad --- /dev/null +++ b/contributing.md @@ -0,0 +1,14 @@ +# Contributing to Apress Source Code + +Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. + +## How to Contribute + +1. Make sure you have a GitHub account. +2. Fork the repository for the relevant book. +3. Create a new branch on which to make your change, e.g. +`git checkout -b my_code_contribution` +4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. +5. Submit a pull request. + +Thank you for your contribution! \ No newline at end of file