piątek, stycznia 08, 2010

Analiza wydajności OpenESB

BPEL w OpenESB wcale nie jest taki wolny. Wołanie procedury NOOP w bazie powoduje, że są sprawdzane jej parametry poprzez oracle.jdbc.OracleDatabaseMetaData.getProcedureColumns, a to natomiast tworzy nowego PreparedStatement-a:

SELECT package_name AS procedure_cat, owner AS procedure_schem, object_name AS procedure_name, argument_name AS column_name,
DECODE(position, 0, 5, DECODE(in_out, 'IN', 1, 'OUT', 4, 'IN/OUT', 2, 0)) AS column_type,
DECODE (data_type, 'CHAR', 1, 'VARCHAR2', 12, 'NUMBER', 3, 'LONG', -1,
'DATE', 91, 'RAW', -3, 'LONG RAW', -4, 'TIMESTAMP', 93, 'TIMESTAMP WITH TIME ZONE', -101, 'TIMESTAMP WITH LOCAL TIME ZONE', -102, 'INTERVAL YEAR TO MONTH', -103,
'INTERVAL DAY TO SECOND', -104, 'BINARY_FLOAT', 100, 'BINAvRY_DOUBLE', 101,
1111) AS data_type,
DECODE(data_type, 'OBJECT', type_owner || '.' || type_name, data_type) AS type_name,
DECODE (data_precision, NULL, data_length, data_precision) AS precision,
data_length AS length, data_scale AS scale, 10 AS radix, 1 AS nullable,
NULL AS remarks, default_value AS column_def, NULL as sql_data_type,
NULL AS sql_datetime_sub, 
DECODE(data_type, 'CHAR', 32767, 'VARCHAR2', 32767, 'LONG', 32767, 'RAW', 32767, 'LONG RAW', 32767,
NULL) AS char_octet_length, (sequence - 1) AS ordinal_position,
'YES' AS is_nullable, NULL AS specific_name, sequence, overload,
default_value 
FROM all_arguments
WHERE owner LIKE :1 ESCAPE '/' AND object_name LIKE :2 ESCAPE '/' AND data_level = 0 
AND package_name LIKE :3 ESCAPE '/' "+
ORDER BY procedure_schem, procedure_name, overload, sequence

który jest strasznie wolny. Należy to wsadzić w cache (org.glassfish.openesb.databasebc.JDBCDenormalizer.populateProcedure):

private static HashMap<String,List<ProcMetaData>> procMetaDataCache = new HashMap<String,List<ProcMetaData>>();
String key = "pcatalog="+pcatalog+",pschema="+pschema+",procName="+procName;
List<ProcMetaData> pmdList = procMetaDataCache.get(key);
if (pmdList==null) {
try
{ pmdList = new LinkedList<ProcMetaData>();
rs = dbmeta.getProcedureColumns(pcatalog, pschema, procName, "%");
while (rs.next()) {
String columnName = rs.getString("COLUMN_NAME");
if(columnName.charAt(0) == '@')
columnName = columnName.substring(1);
int targetSqlType = rs.getInt("DATA_TYPE");
int colType = rs.getShort("COLUMN_TYPE");
String type_Name = rs.getString("TYPE_NAME");
short numericScale = rs.getShort("SCALE");
ProcMetaData pmd = new ProcMetaData(columnName, targetSqlType, colType, type_Name, numericScale);
pmdList.add(pmd);
}
procMetaDataCache.put(key, pmdList); // no sync since it would be difficult or could hurt performance
rs.close();
}

Teraz mamy 22 ms! Quick and dirty fix is here.

0 komentarze: