Last active
August 9, 2018 10:16
-
-
Save daisukenishino2/6ab8fd7a9f6eb0c32782c73dc95c3f27 to your computer and use it in GitHub Desktop.
Open棟梁:バッチ・サンプルの性能測定(2)に使用した、各種リソース情報と、その測定結果。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//********************************************************************************** | |
//* フレームワーク・テストクラス(B層) | |
//********************************************************************************** | |
// テスト用サンプルなので、必要に応じて流用 or 削除して下さい。 | |
//********************************************************************************** | |
//* クラス名 :LayerB | |
//* クラス日本語名 :B層のテスト | |
//* | |
//* 作成日時 :- | |
//* 作成者 :生技セ | |
//* 更新履歴 : | |
//* | |
//* 日時 更新者 内容 | |
//* ---------- ---------------- ------------------------------------------------- | |
//* 20xx/xx/xx XX XX XXXX | |
//********************************************************************************** | |
using RerunnableBatch_sample3.Common; | |
using System; | |
using System.Data; | |
using System.Text; | |
using System.Collections; | |
using Touryo.Infrastructure.Business.Business; | |
using Touryo.Infrastructure.Business.Dao; | |
using Touryo.Infrastructure.Public.Db; | |
namespace RerunnableBatch_sample3.Business | |
{ | |
/// <summary> | |
/// LayerB の概要の説明です | |
/// </summary> | |
public class LayerB : MyFcBaseLogic | |
{ | |
public const int INTERMEDIATE_COMMIT_COUNT = 2000; | |
/// <summary>バッチ処理を実行する</summary> | |
/// <param name="parameter">引数クラス</param> | |
private void UOC_ExecuteBatchProcess(ExecuteBatchProcessParameterValue parameter) | |
{ | |
// 戻り値クラスを生成して、事前に戻り値に設定しておく。 | |
this.ReturnValue = new VoidReturnValue(); | |
// ↓業務処理----------------------------------------------------- | |
DataTable pkTable = new DataTable(); | |
// ↓DBアクセス----------------------------------------------------- | |
// 共通Daoを生成 | |
CmnDao cmnDao = new CmnDao(this.GetDam()); | |
// 動的SQLを指定 | |
cmnDao.SQLFileName = "SelectAllOrderID.xml"; | |
// 共通Daoを実行 | |
cmnDao.ExecSelectFill_DT(pkTable); | |
// ↑DBアクセス----------------------------------------------------- | |
// 戻り値を設定 | |
ArrayList pkList = new ArrayList(); | |
for (int index = 0; index < pkTable.Rows.Count; index++) | |
{ | |
//データテーブルからArrayListに詰め直す | |
pkList.Add(pkTable.Rows[index]["OrderID"]); | |
} | |
// ↑業務処理----------------------------------------------------- | |
int recordCount = pkList.Count; // 全レコード数 | |
int initialIndex = 0; // 処理開始インデックス ※ todo:リラン時に途中から再開する場合は初期値を変更する | |
int transactionCount = Convert.ToInt32(Math.Ceiling(((double)(recordCount - initialIndex)) / INTERMEDIATE_COMMIT_COUNT)); // 更新B層実行回数 | |
int i = 0; | |
for (int transactionIndex = 0; transactionIndex < transactionCount; transactionIndex++) | |
{ | |
ArrayList subPkList; // 主キー一覧(1トランザクション分) | |
int subPkStartIndex; // 主キー(1トランザクション分)の開始位置 | |
int subPkCount; // 主キー数(1トランザクション分) | |
// 取り出す主キーの開始、数を取得 | |
subPkStartIndex = initialIndex + (transactionIndex * INTERMEDIATE_COMMIT_COUNT); | |
if (subPkStartIndex + INTERMEDIATE_COMMIT_COUNT - 1 > recordCount - 1) | |
{ | |
subPkCount = (recordCount - initialIndex) % INTERMEDIATE_COMMIT_COUNT; | |
} | |
else | |
{ | |
subPkCount = INTERMEDIATE_COMMIT_COUNT; | |
} | |
// 主キー一覧(1トランザクション分)を取り出す | |
subPkList = new ArrayList(); | |
subPkList.AddRange(pkList.GetRange(subPkStartIndex, subPkCount)); | |
// ↓業務処理----------------------------------------------------- | |
DataTable dataTable = new DataTable(); //データ一覧(主キーを元に検索したデータ) | |
//Ordersテーブルからデータを検索する | |
// ↓DBアクセス----------------------------------------------------- | |
// 共通Daoを生成 | |
cmnDao = new CmnDao(this.GetDam()); | |
// 動的SQLを指定 | |
cmnDao.SQLFileName = "SelectInOrderID.xml"; | |
// パラメータを設定 | |
cmnDao.SetParameter("OrderID", subPkList); | |
// 共通Daoを実行 | |
//string sql = | |
cmnDao.ExecSelectFill_DT(dataTable); | |
//ExecGenerateSQL(new SQLUtility(DbEnum.DBMSType.SQLServer)); | |
//cmnDao = new CmnDao(this.GetDam()); | |
//cmnDao.SQLText = sql; | |
//cmnDao.ExecSelectFill_DT(dataTable); | |
// ↑DBアクセス----------------------------------------------------- | |
//Orders2テーブルに複数件まとめて追加する。 | |
string insertHeader = "INSERT INTO [Orders2] {0} VALUES {1}"; | |
string columnList = ""; | |
SQLUtility sQLUtility = new SQLUtility(DbEnum.DBMSType.SQLServer); | |
string[] insertSQLParts = sQLUtility.GetInsertSQLParts(dataTable); | |
StringBuilder sb = new StringBuilder(); | |
foreach (string insertSQLPart in insertSQLParts) | |
{ | |
if (string.IsNullOrEmpty(columnList)) | |
{ | |
// columnList | |
columnList = insertSQLPart; | |
} | |
else | |
{ | |
// insertSQLPart | |
sb.Append(string.Format(insertHeader, columnList, insertSQLPart) + Environment.NewLine); | |
} | |
} | |
// 共通Daoでバッチ更新 | |
CmnDao cd = new CmnDao(this.GetDam()); | |
cd.SQLText = sb.ToString(); | |
cd.ExecInsUpDel_NonQuery(); | |
i += INTERMEDIATE_COMMIT_COUNT; | |
Console.WriteLine("1 interval was executed. " + i.ToString()); | |
// ↑業務処理----------------------------------------------------- | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//********************************************************************************** | |
//* フレームワーク・テストクラス(B層) | |
//********************************************************************************** | |
// テスト用サンプルなので、必要に応じて流用 or 削除して下さい。 | |
//********************************************************************************** | |
//* クラス名 :LayerB | |
//* クラス日本語名 :B層のテスト | |
//* | |
//* 作成日時 :- | |
//* 作成者 :生技セ | |
//* 更新履歴 : | |
//* | |
//* 日時 更新者 内容 | |
//* ---------- ---------------- ------------------------------------------------- | |
//* 20xx/xx/xx XX XX XXXX | |
//********************************************************************************** | |
using RerunnableBatch_sample3.Common; | |
using System; | |
using System.Data; | |
using System.Text; | |
using System.Collections; | |
using Touryo.Infrastructure.Business.Business; | |
using Touryo.Infrastructure.Business.Dao; | |
using Touryo.Infrastructure.Public.Db; | |
namespace RerunnableBatch_sample3.Business | |
{ | |
/// <summary> | |
/// LayerB の概要の説明です | |
/// </summary> | |
public class LayerB : MyFcBaseLogic | |
{ | |
public const int INTERMEDIATE_COMMIT_COUNT = 2000; | |
/// <summary>バッチ処理を実行する</summary> | |
/// <param name="parameter">引数クラス</param> | |
private void UOC_ExecuteBatchProcess(ExecuteBatchProcessParameterValue parameter) | |
{ | |
// 戻り値クラスを生成して、事前に戻り値に設定しておく。 | |
this.ReturnValue = new VoidReturnValue(); | |
// ↓業務処理----------------------------------------------------- | |
DataTable dataTable = new DataTable(); | |
// ↓DBアクセス----------------------------------------------------- | |
// 共通Daoを生成 | |
CmnDao cmnDao = new CmnDao(this.GetDam()); | |
// 動的SQLを指定 | |
cmnDao.SQLFileName = "SelectAllOrderID.xml"; | |
// 共通Daoを実行 | |
cmnDao.ExecSelectFill_DT(dataTable); | |
// ↑DBアクセス----------------------------------------------------- | |
// ↑業務処理----------------------------------------------------- | |
// ↓業務処理----------------------------------------------------- | |
//Orders2テーブルに複数件まとめて追加する。 | |
string insertHeader = "INSERT INTO [Orders2] {0} VALUES "; | |
SQLUtility sQLUtility = new SQLUtility(DbEnum.DBMSType.SQLServer); | |
string[] insertSQLParts = sQLUtility.GetInsertSQLParts(dataTable); | |
dataTable = null; // GCへ。 | |
int length = insertSQLParts.Length; | |
StringBuilder sb = new StringBuilder(); | |
// ColumnList | |
sb.Append(string.Format(insertHeader, insertSQLParts[0])); | |
for (int i = 1; i < length; i++) | |
{ | |
// InsertSQLPart | |
sb.Append(Environment.NewLine + insertSQLParts[i] + ", "); | |
//if (sb.Length > 1000) break; | |
} | |
sb.Remove(sb.Length - 3, 2); // ", " を消す。 | |
sb.Append(";"); // ";" を足す。 | |
//Console.WriteLine(sb.ToString()); | |
//Console.ReadKey(); | |
// 共通Daoでバッチ更新 | |
CmnDao cd = new CmnDao(this.GetDam()); | |
cd.SQLText = sb.ToString(); | |
cd.ExecInsUpDel_NonQuery(); | |
// ↑業務処理----------------------------------------------------- | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" ?> | |
<ROOT> | |
SELECT | |
* | |
FROM | |
Orders | |
ORDER BY | |
OrderID | |
</ROOT> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//********************************************************************************** | |
//* リラン可能バッチ処理・サンプル アプリ | |
//********************************************************************************** | |
// テスト用サンプルなので、必要に応じて流用 or 削除して下さい。 | |
//********************************************************************************** | |
//* クラス名 :Program | |
//* クラス日本語名 :サンプル バッチ | |
//* | |
//* 作成日時 :- | |
//* 作成者 :生技 | |
//* 更新履歴 : | |
//* | |
//* 日時 更新者 内容 | |
//* ---------- ---------------- ------------------------------------------------- | |
//* 20xx/xx/xx XX XX XXXX | |
//********************************************************************************** | |
using RerunnableBatch_sample3.Business; | |
using RerunnableBatch_sample3.Common; | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using Touryo.Infrastructure.Business.Util; | |
using Touryo.Infrastructure.Public.Db; | |
using Touryo.Infrastructure.Public.Util; | |
namespace RerunnableBatch_sample3 | |
{ | |
/// <summary>Program</summary> | |
class Program | |
{ | |
/// <summary>Main</summary> | |
static void Main(string[] args) | |
{ | |
// コマンドラインをバラす関数がある。 | |
List<string> valsLst = null; | |
Dictionary<string, string> argsDic = null; | |
PubCmnFunction.GetCommandArgs('/', out argsDic, out valsLst); | |
// 引数クラス値(B層実行用) | |
string screenId = System.Reflection.Assembly.GetExecutingAssembly().Location; | |
string controlId = "-"; | |
string actionType = "SQL"; // argsDic["/DAP"] + "%" + argsDic["/MODE1"] + "%" + argsDic["/MODE2"] + "%" + argsDic["/EXROLLBACK"]; | |
MyUserInfo myUserInfo = new MyUserInfo("userName", "ipAddress"); | |
// B層クラス | |
LayerB layerB = new LayerB(); | |
// 引数クラスを生成 | |
VoidParameterValue selectPkListParameterValue = new VoidParameterValue(screenId, controlId, "SelectPkList", actionType, myUserInfo); | |
//// B層呼出し | |
SelectPkListReturnValue selectPkReturnValue = null; | |
// 性能測定 | |
// 性能測定 - 開始 | |
PerformanceRecorder pr = new PerformanceRecorder(); | |
pr.StartsPerformanceRecord(); | |
// ↓B層実行:バッチ処理を実行(1トランザクション分)---------------------------------------------------- | |
// 引数クラスを生成 | |
ExecuteBatchProcessParameterValue executeBatchProcessParameterValue = new ExecuteBatchProcessParameterValue(screenId, controlId, "ExecuteBatchProcess", actionType, myUserInfo); | |
//executeBatchProcessParameterValue.SubPkList = subPkList; | |
// B層呼出し | |
VoidReturnValue executeBatchProcessReturnValue = (VoidReturnValue)layerB.DoBusinessLogic(executeBatchProcessParameterValue, DbEnum.IsolationLevelEnum.ReadCommitted); | |
// 実行結果確認 | |
if (executeBatchProcessReturnValue.ErrorFlag == true) | |
{ | |
// 結果(業務続行可能なエラー) | |
string error = "ErrorMessageID:" + selectPkReturnValue.ErrorMessageID + "\r\n"; | |
error += "ErrorMessage:" + selectPkReturnValue.ErrorMessage + "\r\n"; | |
error += "ErrorInfo:" + selectPkReturnValue.ErrorInfo + "\r\n"; | |
Console.WriteLine(error); | |
Console.ReadKey(); | |
return; // バッチ処理終了 | |
} | |
// ↑B層実行:バッチ処理を実行(1トランザクション分)---------------------------------------------------- | |
// 性能測定 - 終了 | |
Console.WriteLine(pr.EndsPerformanceRecord()); | |
Console.ReadKey(); | |
} | |
} | |
} |
追加の性能測定2
目的
上記の
の測定モデルは、
の続きで、
「分割コミット」と「疑似フェッチ」を無くし、
これらが性能にどのような影響を与えるを調べるためのものである。
結果
( 1 )
結果として、以下の例外が発生。
System.Data.SqlClient.SqlException (0x80131904): サーバーに要求を送信しているときに、トランスポート レベルの
エラーが発生しました。 (provider: Shared Memory Provider, error: 0 - パイプの他端にプロセスがありません。)
---> System.ComponentModel.Win32Exception (0x80004005): パイプの他端にプロセスがありません。
- Troubleshooting Connectivity #3 – 予期しない接続切断 – Microsoft SQL Server Japan Support Team Blog
https://blogs.msdn.microsoft.com/jpsql/2012/07/16/troubleshooting-connectivity-3/
( 2 )
例外発生を抑止すべく、Insert文を短縮を試みる。
- INSERT ステートメントで複数の値を指定 - 松本崇博 Blog (SQL Server Tips)
http://d.hatena.ne.jp/matu_tak/20100113/1263856222
が、問題解決せず(カラム・リスト短縮のレベルでは解決せず)。
原因
- 100万件のInsert文は、サイズが大き過ぎるため実行不可能。
- DataTableの利用で、バッチEXEのメモリも5.0GBまで膨れたが、
Insert文が巨大過ぎるという話だとPOCO化しても無意味。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
追加の性能測定1
目的
上記の
の測定モデルは、
の続きで、
「分割コミット」から「一括コミット」に変更することで、
コミットが性能にどのような影響を与えるを調べるためのものである。
結果
結果として、性能向上するケースと、性能劣化するケースを観測した。
( 1 ) ローカル・ループバック・アドレス & コミット・インターバル ≒ 100
193,083 ---> 174,496 (性能向上)
( 2 ) ローカル・ループバック・アドレス & コミット・インターバル ≒ 2,000
290,963 ---> 292,086 (大きな変化初めてなし)
( 3 ) ローカルIPアドレス & コミット・インターバル ≒ 100
1053,107 ---> 1235,646 (性能劣化)
( 4 ) ローカルIPアドレス & コミット・インターバル ≒ 2,000
781,757 ---> 858,291 (性能劣化)
原因
特筆すべき、ポイント
( 1 )
結果、( 1 ), ( 2 )の比較。
ローカル・ループバック・アドレスでは、もともとオーバーヘッドが少なく、送信SQL文が長くなることで、
ネットワーク上か、DBMS上で性能劣化が起きたものと考える。
( 2 )
結果、( 3 ), ( 4 )のケースの分析。
ロング・トランザクションで性能劣化が起きる可能性があるもよう。
https://blogs.msdn.microsoft.com/jpsql/2016/05/13/tempdb-%E3%82%92%E5%9C%A7%E7%B8%AE%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AE%E6%B3%A8%E6%84%8F%E7%82%B9%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/