optimisation 2013-07-02
TRANSCRIPT
最適化
最適化
最適化目的
最適化目的
アプリケーション実行速度を向上させること
最適化目的
アプリケーション実行速度を向上させること
最適化目的
アプリケーション実行速度を向上させること
最適なコーディング•ランゲージの特性•コンパイル
最適なハードウェア•メモリ•記憶装置
最適なインデックス設定•プライマリーキー 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レコード数:
最適化