🚫 Ad Blocker Detected

Please disable your AD blocker to continue using this site. Ads help us keep the content free! please press keyboard F5 to refresh page after disabled AD blocker

請關閉廣告攔截器以繼續使用本網站。廣告有助於我們保證內容免費。謝謝! 關閉後請按 F5 刷新頁面

0%

Agenda

前文

之前有跟大家介紹資料庫交易中的ACID,今天我們就來談談常常聽到Lock

在討論Lock前我們必須先了解,為什麼會有Lock?

假如你的系統能保證只有一個使用著操作每個資源,其實也就不用lock存在,但現實生活中往往有個命令對於同一個資源操作.這時候我們為了確保資料正確性,必須使用lock來避免Racing Condition.

在早期系統我們要儲存資料會存放檔案在Disk並使用類似Excel方式來儲存,但這會導致每次讀取只有有一個使用者(因為對於檔案上Lock),被lock資源其他人就無法存入

兩種圍度的Lock

Sql-Server Lock有分兩種圍度

  1. Lock範圍
  2. Lock類型
Read more »

前文

JOIN條件範圍時,執行計畫預估值容易不準確,這也間接導致查詢效能不好.

就算有建立Index也會遇到上述問題

假如我們想要提升JOIN條件範圍效能並讓Index可以發揮最大最用可以怎麼做?

就讓我利用一個範例來跟大家分享.

案例

此範例有使用到三張表

  • Product表:擁有1-10編號產品
  • ReportPeriod表:存放產每期報表的資訊(時間,和是否產報表)
  • T99表:線上產品訂單資訊
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CREATE TABLE [dbo].[Product](
[ProductId] INT NOT NULL
)

CREATE TABLE [dbo].[T99](
[TransactionId] [int] IDENTITY(1,1) NOT NULL,
[Amount] DECIMAL(18,6),
[CreateDate] [datetime2](3) NULL
)
GO

CREATE TABLE [dbo].[ReportPeriod](
[PerioidID] [int] IDENTITY(1,1) NOT NULL,
[ProductId] INT NOT NULL,
[IsGenerate] [bit] NULL,
[StartDate] [datetime2](3) NULL,
[EndDate] [datetime2](3) NULL
) ON [PRIMARY]
GO

我們利用T99.CreateDate來跟ReportPeriod判斷是屬於哪期報表.

Read more »

前文

JOIN條件範圍時,執行計畫預估值容易不準確,這也間接導致查詢效能不好.

就算有建立Index也會遇到上述問題

假如我們想要提升JOIN條件範圍效能並讓Index可以發揮最大最用可以怎麼做?

就讓我利用一個範例來跟大家分享.

案例

此範例有使用到三張表

  • Product表:擁有1-10編號產品
  • ReportPeriod表:存放產每期報表的資訊(時間,和是否產報表)
  • T99表:線上產品訂單資訊
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CREATE TABLE [dbo].[Product](
[ProductId] INT NOT NULL
)

CREATE TABLE [dbo].[T99](
[TransactionId] [int] IDENTITY(1,1) NOT NULL,
[Amount] DECIMAL(18,6),
[CreateDate] [datetime2](3) NULL
)
GO

CREATE TABLE [dbo].[ReportPeriod](
[PerioidID] [int] IDENTITY(1,1) NOT NULL,
[ProductId] INT NOT NULL,
[IsGenerate] [bit] NULL,
[StartDate] [datetime2](3) NULL,
[EndDate] [datetime2](3) NULL
) ON [PRIMARY]
GO

我們利用T99.CreateDate來跟ReportPeriod判斷是屬於哪期報表.

Read more »

前言

假如要判斷資料是否存在於資料表中,存在就更新,不存在就新增.

這時我們可以使用Merge來幫助我們完成.

當兩個資料表有複雜的比對的特性時,MERGE陳述式的條件式行為表現最佳。

有了Merge我們就不用使用IF EXISTS.

一切都是這麼完美…

直到到有一天Merge在Prod撞到一個問題..

問題描述

使用語法user defined table type & Table如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

CREATE TABLE [dbo].[PriceLimitation](
[CategoryID] [int] NOT NULL,
[ProdcutGroupID] [smallint] NOT NULL,
[UserID] [int] NOT NULL,
[StakeAmount] [numeric](18, 4) NOT NULL,
[ProductID] [smallint] NOT NULL,
CONSTRAINT [PK_PriceLimitation] PRIMARY KEY CLUSTERED
(
[UserID] ASC,
[CategoryID] ASC,
[ProductID] ASC,
[ProdcutGroupID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE TYPE [dbo].[uftt_PriceLimit] AS TABLE(
[CategoryID] [int] NOT NULL,
[ProdcutGroupID] [smallint] NOT NULL,
[UserID] [int] NOT NULL,
[StakeAmount] [numeric](18, 4) NOT NULL,
[ProductID] [smallint] NOT NULL,
PRIMARY KEY CLUSTERED
(
[UserID] ASC,
[CategoryID] ASC,
[ProductID] ASC,
[ProdcutGroupID] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
Read more »

前言

假如要判斷資料是否存在於資料表中,存在就更新,不存在就新增.

這時我們可以使用Merge來幫助我們完成.

當兩個資料表有複雜的比對的特性時,MERGE陳述式的條件式行為表現最佳。

有了Merge我們就不用使用IF EXISTS.

一切都是這麼完美…

直到到有一天Merge在Prod撞到一個問題..

問題描述

使用語法user defined table type & Table如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

CREATE TABLE [dbo].[PriceLimitation](
[CategoryID] [int] NOT NULL,
[ProdcutGroupID] [smallint] NOT NULL,
[UserID] [int] NOT NULL,
[StakeAmount] [numeric](18, 4) NOT NULL,
[ProductID] [smallint] NOT NULL,
CONSTRAINT [PK_PriceLimitation] PRIMARY KEY CLUSTERED
(
[UserID] ASC,
[CategoryID] ASC,
[ProductID] ASC,
[ProdcutGroupID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE TYPE [dbo].[uftt_PriceLimit] AS TABLE(
[CategoryID] [int] NOT NULL,
[ProdcutGroupID] [smallint] NOT NULL,
[UserID] [int] NOT NULL,
[StakeAmount] [numeric](18, 4) NOT NULL,
[ProductID] [smallint] NOT NULL,
PRIMARY KEY CLUSTERED
(
[UserID] ASC,
[CategoryID] ASC,
[ProductID] ASC,
[ProdcutGroupID] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
Read more »

前言

資料庫系統在寫入或新增資料時,為了確保交易正確可靠性,所以具備

  • 原子性(atomicity,稱不可分割性)
  • 一致性(consistency)
  • 隔離性(isolation,稱獨立性)
  • 持久性(durability)

這就是我們說的ACID.

下面我會跟大家簡述ACID.

Atomicity(原子性)

所有Logical Unit都必須符合原子性

整個流程要不是全部成功,不然就整段失敗,不會有部分完成

sample data.

1
2
3
4
5
6
7
8
9
IF (SELECT OBJECT_ID('dbo.ProductTest')) IS NOT NULL   
DROP TABLE dbo.ProductTest;

CREATE TABLE dbo.ProductTest ( ProductID INT CONSTRAINT ValueEqualsOne CHECK (ProductID = 1));

CREATE TABLE Product (ProductID INT)
INSERT INTO dbo.Product
SELECT 2

Read more »

前言

資料庫系統在寫入或新增資料時,為了確保交易正確可靠性,所以具備

  • 原子性(atomicity,稱不可分割性)
  • 一致性(consistency)
  • 隔離性(isolation,稱獨立性)
  • 持久性(durability)

這就是我們說的ACID.

下面我會跟大家簡述ACID.

Atomicity(原子性)

所有Logical Unit都必須符合原子性

整個流程要不是全部成功,不然就整段失敗,不會有部分完成

sample data.

1
2
3
4
5
6
7
8
9
IF (SELECT OBJECT_ID('dbo.ProductTest')) IS NOT NULL   
DROP TABLE dbo.ProductTest;

CREATE TABLE dbo.ProductTest ( ProductID INT CONSTRAINT ValueEqualsOne CHECK (ProductID = 1));

CREATE TABLE Product (ProductID INT)
INSERT INTO dbo.Product
SELECT 2

Read more »

前言:

下面有兩個虛擬程式碼

1
2
3
4
5
int times = 30000000;
string s = string.Empty;

s = $"{times}";
s = $"{times.ToString()}";

請問下面這兩段程式碼有沒有差別?

1
2
s = $"{times}";
s = $"{times.ToString()}";

$""這個程式碼是string.Format()語法糖

如果知道差別的同學,恭喜你已經可以下課了

如果不知道差別也沒關係,讓我細細講述.

String.Format方法簽章

String.Format方法有一個重載方法,可以看到裡面吃參數是params object[]這可以讓我們傳進東西當作參數(他會在方法中呼叫ToString方法).

Read more »

前言:

BoxingUnBoxing在.net中,我們可能在無意識使用到但這個事情確會造成一些效能影響…

.NET兩種類型

在.NET有分兩種類型

  1. 值類型(int,double,char….)
  2. 參考類型(自行宣告的類別,string….)

而存放資料的方式也有兩種:

  1. 堆疊Stack  
  2. 堆積Heap

談談Boxing和UnBoxing之前,我們先來了解StackHeap

值類型(Value Type)會存取在Stack記憶體區塊中

參考類型(Reference Type)內容會在Heap記憶體區塊上,Stack會指向Heap上記憶體位置(有點像c++傳址)

Read more »

什麼是統計值

SQL Server的QO(Query Optimizer)透過cost-based model來選擇一個最合適計畫(估算成本最低)來執行查詢

 注意每個執行計畫是使用CPU來做估算,使用過的執行計畫一般會Cache起來已便下次使用

QO會依照基數估計(Cardinality estimation)來產生執行計畫,基數估計扮演一個很重要的角色

SQL Server統計值是對於每個Index或欄位資料分布做紀錄,任何型態都支援統計值資料.

過期的統計值資料導致QO誤判產生不良執行計畫

在我們建立Index時,統計值會自動創建。此外當欄位在查詢裡被使用(作為WHERE條件的一部分,group by子句,join條件)統計值會被自動建立

何時建立統計值?

每個索引都會有自己個統計資訊,在UI查看統計資訊如下圖.

Read more »