Optimisation 2013-07-02

Post on 19-Jun-2015

195 views 3 download

Transcript of Optimisation 2013-07-02

最適化

最適化

最適化目的

最適化目的

アプリケーション実行速度を向上させること

最適化目的

アプリケーション実行速度を向上させること

最適化目的

アプリケーション実行速度を向上させること

最適なコーディング•ランゲージの特性•コンパイル

最適なハードウェア•メモリ•記憶装置

最適なインデックス設定•プライマリーキー or 低選択性•クエリ重視 or 並び替え

ハードウェア

ハードウェア64ビット版サーバー

ハードウェア64ビット版サーバー

http://www.4d.com/jp/support/resources.html

ハードウェア64ビット版サーバー

http://www.4d.com/jp/support/resources.html

32bits 64bits

キャッシュ上限 2.3GB unlimited

1度目のクエリ 69s 52s

2度目のクエリ 37s 1.4s

ハードウェア64ビット版サーバー

http://www.4d.com/jp/support/resources.html

32bits 64bits

キャッシュ上限 2.3GB unlimited

1度目のクエリ 69s 52s

2度目のクエリ 37s 1.4s

インデックス無7,500,000レコード数:

3.2GBデータファイル:

ハードウェア64ビット版サーバー

http://www.4d.com/jp/support/resources.html

32bits 64bits

キャッシュ上限 2.3GB unlimited

ソート平均値 839s 108s

インデックス無7,500,000レコード数:

3.2GBデータファイル:

ハードウェア

ハードウェアSSD (Solid State Drive)

ハードウェアSSD (Solid State Drive)

HD SSD

1度目の検査 11:00 2:00

圧縮 17:00 5:00

2度目の検査 3:00 0:30

31:00 7:30

ハードウェアSSD (Solid State Drive)

HD SSD

1度目の検査 11:00 2:00

圧縮 17:00 5:00

2度目の検査 3:00 0:30

31:00 7:30

50GiBデータファイル:

ランゲージの特性

ランゲージの特性配列の合計

C_POINTER($1)C_REAL($0)C_LONGINT($i)

For($i;1;Size of array($1->)) $0:=$0+$1->{$i}End for

ランゲージの特性配列の合計

C_POINTER($1)C_REAL($0)C_LONGINT($i)

For($i;1;Size of array($1->)) $0:=$0+$1->{$i}End for

配列の合計ランゲージの特性

C_POINTER($1)C_REAL($0)C_LONGINT($i)

For($i;1;Size of array($1->)) $0:=$0+$1->{$i}End for

配列の要素を逐一ポインタで解決して加算

配列の合計ランゲージの特性

C_POINTER($1)C_REAL($0)C_LONGINT($i)ARRAY LONGINT($arrCopy)

COPY ARRAY ($1->;$arrCopy)For ($i;1;Size of array($arrCopy)) $0:=$0+$arrCopy{$i}End for

配列の合計ランゲージの特性

C_POINTER($1)C_REAL($0)C_LONGINT($i)ARRAY LONGINT($arrCopy)

COPY ARRAY ($1->;$arrCopy)For ($i;1;Size of array($arrCopy)) $0:=$0+$arrCopy{$i}End for

配列の合計ランゲージの特性

C_POINTER($1)C_REAL($0)C_LONGINT($i)ARRAY LONGINT($arrCopy)

COPY ARRAY ($1->;$arrCopy)For ($i;1;Size of array($arrCopy)) $0:=$0+$arrCopy{$i}End for

配列をコピー(参照カウントをインクリメント)して加算

配列の合計ランゲージの特性

配列の合計ランゲージの特性

C_POINTER($1)C_REAL($0)

$0:=Sum($1->)

C_POINTER($1)C_REAL($0)

$0:=Sum($1->)

配列の合計ランゲージの特性

C_POINTER($1)C_REAL($0)

$0:=Sum($1->)

配列の合計ランゲージの特性

配列に統計関数を使用して加算

C_POINTER($1)C_REAL($0)

$0:=Sum($1->)

配列の合計ランゲージの特性

配列の合計ランゲージの特性

COPY$1->{$i}

インタプリタ版

配列の合計ランゲージの特性

COPY$1->{$i}

Sumインタプリタ版

配列の合計ランゲージの特性

COPY$1->{$i}

コンパイル版

配列の合計ランゲージの特性

COPY$1->{$i}

Sumコンパイル版

ランゲージの特性

ランゲージの特性文字列の比較

ランゲージの特性文字列の比較

C_TEXT($1;$2)C_BOOLEAN($0)

C_LONGINT($i;$L_max)

$L_max:=Length($1)If ($L_max=Length($2)) $0:=True For ($i;1;$L_max) If (Character code($1[[$i]])#Character code($2[[$i]])) $0:=False $i:=$L_max End if End for End if

ランゲージの特性文字列の比較

C_TEXT($1;$2)C_BOOLEAN($0)

C_LONGINT($i;$L_max)

$L_max:=Length($1)If ($L_max=Length($2)) $0:=True For ($i;1;$L_max) If (Character code($1[[$i]])#Character code($2[[$i]])) $0:=False $i:=$L_max End if End for End if

ランゲージの特性文字列の比較

コンパイル版インタプリタ版

ランゲージの特性文字列の比較

$L_max:=Length($1)If ($L_max=Length($2)) $0:=True TEXT TO BLOB ($1;$blob1;UTF8 text without length) TEXT TO BLOB ($2;$blob2;UTF8 text without length) $L_max:=BLOB size($blob1) If ($L_max=BLOB size($blob2)) $0:=True For ($i;0;$L_max-1) If ($blob1{$i}#$blob2{$i}) $0:=False $i:=$L_max End if End for End if End if

ランゲージの特性文字列の比較

$L_max:=Length($1)If ($L_max=Length($2)) $0:=True TEXT TO BLOB ($1;$blob1;UTF8 text without length) TEXT TO BLOB ($2;$blob2;UTF8 text without length) $L_max:=BLOB size($blob1) If ($L_max=BLOB size($blob2)) $0:=True For ($i;0;$L_max-1) If ($blob1{$i}#$blob2{$i}) $0:=False $i:=$L_max End if End for End if End if

ランゲージの特性文字列の比較

$L_max:=Length($1)If ($L_max=Length($2)) $0:=True TEXT TO BLOB ($1;$blob1;UTF8 text without length) TEXT TO BLOB ($2;$blob2;UTF8 text without length) $L_max:=BLOB size($blob1) If ($L_max=BLOB size($blob2)) $0:=True For ($i;0;$L_max-1) If ($blob1{$i}#$blob2{$i}) $0:=False $i:=$L_max End if End for End if End if

ランゲージの特性文字列の比較

$L_max:=Length($1)If ($L_max=Length($2)) $0:=True TEXT TO BLOB ($1;$blob1;UTF8 text without length) TEXT TO BLOB ($2;$blob2;UTF8 text without length) $L_max:=BLOB size($blob1) If ($L_max=BLOB size($blob2)) $0:=True For ($i;0;$L_max-1) If ($blob1{$i}#$blob2{$i}) $0:=False $i:=$L_max End if End for End if End if

Length BLOB Size

"アイウエオ" 5 15

"アイウエオ" 5 10

ランゲージの特性文字列の比較

コンパイル版インタプリタ版

ランゲージの特性文字列の比較

C_TEXT($1;$2)C_BOOLEAN($0)

Case of : (Length($1)#Length($2)) : (Position($1;$2;*)#1)Else $0:=TrueEnd case

ランゲージの特性文字列の比較

C_TEXT($1;$2)C_BOOLEAN($0)

Case of : (Length($1)#Length($2)) : (Position($1;$2;*)#1)Else $0:=TrueEnd case

ランゲージの特性文字列の比較

C_TEXT($1;$2)C_BOOLEAN($0)

Case of : (Length($1)#Length($2)) : (Position($1;$2;*)#1)Else $0:=TrueEnd case

文字コードに基づいて文字列の位置を判定

ランゲージの特性文字列の比較

C_TEXT($1;$2)C_BOOLEAN($0)

Case of : (Length($1)#Length($2)) : (Position($1;$2;*)#1)Else $0:=TrueEnd case

ランゲージの特性文字列の比較

Position文字コード比較

ランゲージの特性

ランゲージの特性文字列の抽出

ランゲージの特性$T_buffer:=$T_final

Repeat $L_pos:=Position("\r";$T_buffer) If ($L_pos>0) $T_line:=Substring($T_buffer;1;$L_pos-1) $T_buffer:=Substring($T_buffer;$L_pos+1) Else $T_line:=$T_buffer $T_buffer:="" End if // ...use $T_line...Until ($T_buffer="")

文字列の抽出

ランゲージの特性$T_buffer:=$T_final

Repeat $L_pos:=Position("\r";$T_buffer) If ($L_pos>0) $T_line:=Substring($T_buffer;1;$L_pos-1) $T_buffer:=Substring($T_buffer;$L_pos+1) Else $T_line:=$T_buffer $T_buffer:="" End if // ...use $T_line...Until ($T_buffer="")

文字列の抽出

ランゲージの特性$L_offsetMax:=Length($T_final)$L_offset:=1Repeat $L_pos:=Position("\r";$T_final;$L_offset) If ($L_pos>0) $T_line:=Substring($T_final;$L_offset;$L_pos-$L_offset) $L_offset:=$L_pos+1 Else $T_line:=Substring($T_final;$L_offset) $L_offset:=$L_offsetMax End if // ...use $T_line...Until ($L_offset>=$L_offsetMax)

文字列の抽出

ランゲージの特性文字列の抽出

$L_offsetMax:=Length($T_final)$L_offset:=1Repeat $L_pos:=Position("\r";$T_final;$L_offset) If ($L_pos>0) $T_line:=Substring($T_final;$L_offset;$L_pos-$L_offset) $L_offset:=$L_pos+1 Else $T_line:=Substring($T_final;$L_offset) $L_offset:=$L_offsetMax End if // ...use $T_line...Until ($L_offset>=$L_offsetMax)

ランゲージの特性文字列の抽出

$L_offsetMax:=Length($T_final)$L_offset:=1Repeat $L_pos:=Position("\r";$T_final;$L_offset) If ($L_pos>0) $T_line:=Substring($T_final;$L_offset;$L_pos-$L_offset) $L_offset:=$L_pos+1 Else $T_line:=Substring($T_final;$L_offset) $L_offset:=$L_offsetMax End if // ...use $T_line...Until ($L_offset>=$L_offsetMax)

判定のスタート位置を指定

ランゲージの特性文字列の抽出

$L_offsetMax:=Length($T_final)$L_offset:=1Repeat $L_pos:=Position("\r";$T_final;$L_offset) If ($L_pos>0) $T_line:=Substring($T_final;$L_offset;$L_pos-$L_offset) $L_offset:=$L_pos+1 Else $T_line:=Substring($T_final;$L_offset) $L_offset:=$L_offsetMax End if // ...use $T_line...Until ($L_offset>=$L_offsetMax)

ランゲージの特性文字列の抽出

0

100

200

300

400

500

600

700

800

0 2,000 4,000 6,000 8,000 10,000 12,000 14,000 16,000 18,000 20,000

Mill

isec

onds

テキストの行数

インタプリタ版 コンパイル版 インタプリタ版 (*) コンパイル版 (*)

ランゲージの特性文字列の抽出

* 判定のスタート位置を指定

ランゲージの特性

ランゲージの特性文字列の連結

ランゲージの特性

$str:=""For ($i;1;Size of array($theArr)) $str:=$str+$theArr{$i}End for

文字列の連結

ランゲージの特性

$str:=""For ($i;1;Size of array($theArr)) $str:=$str+$theArr{$i}End for

文字列の連結

ランゲージの特性

$str:=$totalLength*"-"$pos:=1For ($i;1;Size of array($theArr)) $str:=Change string($str;$theArr{$i};$pos) $pos:=$pos+Length($theArr{$i})End for

文字列の連結

ランゲージの特性

$str:=$totalLength*"-"$pos:=1For ($i;1;Size of array($theArr)) $str:=Change string($str;$theArr{$i};$pos) $pos:=$pos+Length($theArr{$i})End for

文字列の連結

ランゲージの特性文字列の連結

1,000

2,000

3,000

4,000

5,000

6,000

10,000 30,000 50,000 70,000 90,000

94847769585540272013

6,292

5,293

3,941

3,009

2,232

1,515

959522

21240

Mill

isec

onds

連結 置換 コンパイル版

ランゲージの特性文字列の連結

ランゲージの特性文字列の連結

ランゲージの特性

inArray = PA_GetVariableParameter( params, 1);count = PA_GetArrayNbElements(inArray);

totalLength = 0;for(i = 1; i <= count; i++){! totalLength += PA_GetStringInArray(inArray, i).fLength;}

finalStr = (PA_Unichar *) calloc( totalLength * 1.5, sizeof(PA_Unichar));ptr = (char *) finalStr;for(i = 1; i <= count; i++){! theString = ( * (PA_Unistring**) (inArray.uValue.fArray.fData) )[i];! PA_MoveBlock(theString.fString, ptr, theString.fLength * sizeof(PA_Unichar));! ptr += (theString.fLength * sizeof(PA_Unichar));}PA_ReturnString( params, finalStr);

文字列の連結

ランゲージの特性文字列の連結

20

40

60

80

100

Milliseconds

13 20 2740

55 5869

7784

94

3 8 99 11 14 16 23 24 27

10,00020,00030,000

40,00050,000

60,00070,000

80,00090,000

100,000

置換 プラグイン

ランゲージの特性文字列の連結

コンパイル版

新規プロセス

C_BOOLEAN($1;$B_doIt)

If (Count parameters>0) $B_doIt:=$1End if

If (Not($B_doIt)) $L_ignore:=New process(Current method name;

512*1024;"New order";True)Else

End if

新規プロセス

新規プロセスC_BOOLEAN($1;$B_doIt)

If (Count parameters>0) $B_doIt:=$1End if

If (Not($B_doIt)) $L_ignore:=New process(Current method name;

512*1024;"New order";True)Else

End if

新規プロセスC_BOOLEAN($1;$B_doIt)

If (Count parameters>0) $B_doIt:=$1End if

If (Not($B_doIt)) $L_ignore:=New process(Current method name;

512*1024;"New order";True)Else

End if

プロセス作成と同時にツインプロセスを作成

新規プロセスC_BOOLEAN($1;$B_doIt)

If (Count parameters>0) $B_doIt:=$1End if

If (Not($B_doIt)) $L_ignore:=New process(Current method name;

512*1024;"New order";True)Else

End if

レコードにアクセスするまでツインプロセスの作成は延期

新規プロセス

0

27,500

55,000

82,500

110,000

Milliseconds

1,3271,316

100,195

1,433v12v13

ローカルグローバル

1,000プロセス数:

新規プロセス

コンパイル

コンパイル

For ($i;1;$max) $aText:=$aText+$anArray{$i}+Char(9)End for

For ($i;1;$max) $aText:=$aText+$anArray{$i}+"\t"End for

コンパイル

For ($i;1;$max) $aText:=$aText+$anArray{$i}+Char(9)End for

For ($i;1;$max) $aText:=$aText+$anArray{$i}+"\t"End for

コンパイル

For ($i;1;$max) $aText:=$aText+$anArray{$i}+Char(9)End for

For ($i;1;$max) $aText:=$aText+$anArray{$i}+"\t"End for

Bad

Good!

コンパイル

コンパイル

C_BOOLEAN($0)C_LONGINT($L_platform)PLATFORM PROPERTIES ($L_platform)$0:=($L_platform=Windows)

C_BOOLEAN($0)C_LONGINT(<>envL_platform)If (<>env_L_platform=0) PLATFORM PROPERTIES (<>envL_platform)End if$0:=(<>env_L_platform=Windows)

コンパイル

C_BOOLEAN($0)C_LONGINT($L_platform)PLATFORM PROPERTIES ($L_platform)$0:=($L_platform=Windows)

C_BOOLEAN($0)C_LONGINT(<>envL_platform)If (<>env_L_platform=0) PLATFORM PROPERTIES (<>envL_platform)End if$0:=(<>env_L_platform=Windows)

コンパイル

C_BOOLEAN($0)C_LONGINT($L_platform)PLATFORM PROPERTIES ($L_platform)$0:=($L_platform=Windows)

C_BOOLEAN($0)C_LONGINT(<>envL_platform)If (<>env_L_platform=0) PLATFORM PROPERTIES (<>envL_platform)End if$0:=(<>env_L_platform=Windows)

Bad

Good!

コンパイル

0

1,000

2,000

3,000

4,000

Milliseconds

3,914

101

1,433

3インタプリタ版

コンパイル版

関数コールインタープロセス

100,000コール数:

コンパイル

コンパイル

コンパイル

C_TEXT($0)If (Env_B_IsWindows) $0:="¥¥"Else $0:=":"End if

C_TEXT($0)$0:=Folder separator

コンパイル

C_TEXT($0)If (Env_B_IsWindows) $0:="¥¥"Else $0:=":"End if

C_TEXT($0)$0:=Folder separator

コンパイル

C_TEXT($0)If (Env_B_IsWindows) $0:="¥¥"Else $0:=":"End if

C_TEXT($0)$0:=Folder separator

Bad

Good!

コンパイル

コンパイル

For ($i;1;$max) $aText:=$aText+$anArray{$i}+"\t"End for

コンパイル

For ($i;1;$max) $aText:=$aText+$anArray{$i}+"\t"End for

コンパイル

デフォルトの型指定:

For ($i;1;$max) $aText:=$aText+$anArray{$i}+"\t"End for

コンパイル

デフォルトの型指定:

C_REAL C_LONGINT

For ($i;1;$max) $aText:=$aText+$anArray{$i}+"\t"End for

コンパイル

デフォルトの型指定:

C_REAL C_LONGINT

For ($i;1;$max) $aText:=$aText+$anArray{$i}+"\t"End for

Good!Bad

コンパイル

0

50

100

150

200

Milliseconds

163

24

C_REAL

C_LONGINT

コンパイル

10,000,000ループ数:

コンパイル

コンパイル

If ($aString="")

If (Length($aString)=0)

コンパイル

If ($aString="")

If (Length($aString)=0)

コンパイル

Good!

If ($aString="")

If (Length($aString)=0)

Bad

 無駄なリクエスト

 無駄なリクエスト

QUERY ([Pizzas];[Pizzas]WithOnions=True) FIRST RECORD ([Pizzas])

 無駄なリクエスト

QUERY ([Pizzas];[Pizzas]WithOnions=True) FIRST RECORD ([Pizzas])

 無駄なリクエスト

QUERY ([Pizzas];[Pizzas]WithOnions=True) FIRST RECORD ([Pizzas])

無駄: 1度目のリクエストで済んだことを繰り返している

 無駄なリクエスト

QUERY ([Pizzas];[Pizzas]WithOnions=True) FIRST RECORD ([Pizzas])

無駄: 1度目のリクエストで済んだことを繰り返している無駄: 全フィールドのデータを転送している(BLOBも)

 無駄なリクエスト

QUERY ([Pizzas];[Pizzas]WithOnions=True) FIRST RECORD ([Pizzas])

無駄: 1度目のリクエストで済んだことを繰り返している無駄: 全フィールドのデータを転送している(BLOBも)バグ: 2度目のロードでレコードがロックされる可能性

 無駄なリクエスト

 無駄なリクエスト

QUERY ([Invoices];...)CREATE SET ([Customers];"CustInvoices")FIRST RECORD ([Invoices])While (Not(End selection([Invoices]))) QUERY ([Customers];[Customers]ID=[Invoices]CustomerID) ADD TO SET ([Customers];"CustInvoices") NEXT RECORD ([Invoices])End while USE SET ("CustInvoices")

 無駄なリクエスト

QUERY ([Invoices];...)CREATE SET ([Customers];"CustInvoices")FIRST RECORD ([Invoices])While (Not(End selection([Invoices]))) QUERY ([Customers];[Customers]ID=[Invoices]CustomerID) ADD TO SET ([Customers];"CustInvoices") NEXT RECORD ([Invoices])End while USE SET ("CustInvoices")

× リクエスト

 無駄なリクエスト

QUERY ([Invoices];...)CREATE SET ([Customers];"CustInvoices")FIRST RECORD ([Invoices])While (Not(End selection([Invoices]))) QUERY ([Customers];[Customers]ID=[Invoices]CustomerID) ADD TO SET ([Customers];"CustInvoices") NEXT RECORD ([Invoices])End while USE SET ("CustInvoices")

× リクエスト + リクエスト

 無駄なリクエスト

QUERY ([Invoices];...)CREATE SET ([Customers];"CustInvoices")FIRST RECORD ([Invoices])While (Not(End selection([Invoices]))) QUERY ([Customers];[Customers]ID=[Invoices]CustomerID) ADD TO SET ([Customers];"CustInvoices") NEXT RECORD ([Invoices])End while USE SET ("CustInvoices")

× リクエスト + リクエスト + リクエスト

 無駄なリクエスト

QUERY ([Invoices];...)CREATE SET ([Customers];"CustInvoices")FIRST RECORD ([Invoices])While (Not(End selection([Invoices]))) QUERY ([Customers];[Customers]ID=[Invoices]CustomerID) ADD TO SET ([Customers];"CustInvoices") NEXT RECORD ([Invoices])End while USE SET ("CustInvoices")

× リクエスト + リクエスト + リクエスト × レコード数

 無駄なリクエスト

QUERY ([Invoices];...)CREATE SET ([Customers];"CustInvoices")FIRST RECORD ([Invoices])While (Not(End selection([Invoices]))) QUERY ([Customers];[Customers]ID=[Invoices]CustomerID) ADD TO SET ([Customers];"CustInvoices") NEXT RECORD ([Invoices])End while USE SET ("CustInvoices")

× リクエスト + リクエスト + リクエスト × レコード数 =

 無駄なリクエスト

QUERY ([Invoices];...)CREATE SET ([Customers];"CustInvoices")FIRST RECORD ([Invoices])While (Not(End selection([Invoices]))) QUERY ([Customers];[Customers]ID=[Invoices]CustomerID) ADD TO SET ([Customers];"CustInvoices") NEXT RECORD ([Invoices])End while USE SET ("CustInvoices")

× リクエスト + リクエスト + リクエスト × レコード数 = 無駄 無駄 無駄 無駄 無駄 無駄 無駄 無駄

 無駄なリクエストQUERY ([Invoices];...) RELATE ONE SELECTION ([Invoices];[Customers])

インデックス

インデックス

B-Tree

Cluster

インデックス

B-Tree

Cluster

インデックスキー: 値が該当するレコード

インデックス

B-Tree

Cluster インデックスキー: 値が該当するレコードのビットマップ

インデックスキー: 値が該当するレコード

インデックス

B-Tree

Cluster インデックスキー: 値が該当するレコードのビットマップ

インデックスキー: 値が該当するレコード

インデックス

id: 0

id: 3

id: 2

id: 4

id: 5

id: 6

id: 1

B-Tree

Cluster インデックスキー: 値が該当するレコードのビットマップ

インデックスキー: 値が該当するレコード

インデックス

B-Treeインデックスキー: 値が該当するレコード

id: 0

id: 3

id: 2

id: 4

id: 5

id: 6

id: 1Blue

Red

Blue

Blue

Blue

Red

Red

インデックス

id: 0

id: 3

id: 2

id: 4

id: 5

id: 6

B-Treeインデックスキー: 値が該当するレコード

id: 1Blue

Red

Blue

Blue

Blue

Red

Red

インデックス

id: 0

id: 3

id: 2

id: 4

id: 5

id: 6

id: 1

Cluster インデックスキー: 値が該当するレコードのビットマップ

Blue

Red

インデックス

id: 0

id: 3

id: 2

id: 4 id: 5

id: 6

id: 1

Cluster インデックスキー: 値が該当するレコードのビットマップ

Blue

Red

インデックス

Cluster インデックスキー: 値が該当するレコードのビットマップ

Blue

Red

0101110

1010001

id: 0

id: 3

id: 2

id: 4

id: 5

id: 6

id: 1

インデックス

Cluster インデックスキー: 値が該当するレコードのビットマップ

Blue

Red

0101110

1010001

id: 0

id: 3

id: 2

id: 4

id: 5

id: 6

id: 1

インデックス

Cluster インデックスキー: 値が該当するレコードのビットマップ

Blue

Red

0101110

1010001

id: 0

id: 3

id: 2

id: 4

id: 5

id: 6

id: 1

* 実際にはインデックスページ(ビットテーブル or 圧縮)で管理されている

インデックス

Cluster 低選択性データに適している

Blue

Red

0101110

1010001

id: 0

id: 3

id: 2

id: 4

id: 5

id: 6

id: 1

low-selectivity

インデックス

Cluster 低選択性データに適しているDISTINCT VALUESは圧倒的に速い

Blue

Red

0101110

1010001

id: 0

id: 3

id: 2

id: 4

id: 5

id: 6

id: 1

low-selectivity

インデックス

Clusterlow-selectivity

低選択性データに適しているDISTINCT VALUESは圧倒的に速い

インデックス

Clusterlow-selectivity

high-selectivity

B-Tree 高選択性データに適している(例: プライマリーキー)並び替えはClusterよりも速い

低選択性データに適しているDISTINCT VALUESは圧倒的に速い

0

150

300

450

Milliseconds

30.93

346.4

0.09

5.4

259.5322.2270.8

435.4

B-Tree ClusterB-TreeCluster

DISTINCT VALUES

QUERY5,000,000レコード数:

値の範囲: 1~10

プライマリーキー

0

125

250

Milliseconds

164.82

209.1

160.02

241.25

B-TreeClusterB-TreeCluster

ORDER BY

値の範囲: 1~10

プライマリーキー

5,000,000レコード数:

最適化