We use SQLDataSource for almost all of our data access. I'm doing some benchmark testing of data intensive operations and would like some advice on how to optimize our code. As a test, I've created a simple table with an auto-generated primary key and six other columns, along with an index over two of the other columns.
To test performance of inserts and updates I've created a simple DMI class that does 500 inserts into the table then fetches each record using the indexed fields and updates it using the primary key.
Can you please take a look at the code and let me know if there is a more efficient way to do this?
The table and index definitions.
The ds.xml
The DMI class. You'll notice it also deletes the records created by previous tests first. Not too concerned about that since it doesn't reflect an real-life scenario.
The newRequestInContext method. We use this method whenever we create a server side DSRequest so it has access to the same context as the main request that came from the client.
To test performance of inserts and updates I've created a simple DMI class that does 500 inserts into the table then fetches each record using the indexed fields and updates it using the primary key.
Can you please take a look at the code and let me know if there is a more efficient way to do this?
The table and index definitions.
Code:
CREATE TABLE BENCHMARK ( ID INTEGER GENERATED ALWAYS AS IDENTITY, FIELD1 CHAR(10) CCSID 937 NOT NULL DEFAULT '' , FIELD2 CHAR(10) CCSID 937 NOT NULL DEFAULT '' , FIELD3 CHAR(10) CCSID 937 NOT NULL DEFAULT '' , FIELD4 CHAR(10) CCSID 937 NOT NULL DEFAULT '' , FIELD5 CHAR(10) CCSID 937 NOT NULL DEFAULT '' , FIELD6 CHAR(10) CCSID 937 NOT NULL DEFAULT '' , PRIMARY KEY( ID ) ) CREATE UNIQUE INDEX BENCHMARKA ON BENCHMARK ( FIELD1 ASC , FIELD2 ASC ) ;
Code:
<DataSource ID="benchmark" dataFormat="iscServer" serverType="sql" dbName="as400" sparseUpdates="true" tableName="benchmark" serverConstructor="com.islandpacific.gui.server.customDataSource.BenchmarkDS"> <!-- Datasource used for benchmark testing. --> <fields> <field name="id" title="id" type="sequence" primaryKey="true"/> <field name="field1" title="field1" type="text"/> <field name="field2" title="field2" type="text"/> <field name="field3" title="field3" type="text"/> <field name="field4" title="field4" type="text"/> <field name="field5" title="field5" type="text"/> <field name="field6" title="field6" type="text"/> </fields> <operationBindings> <operationBinding operationType="remove" allowMultiUpdate="true"/> </operationBindings> </DataSource>
Code:
package com.islandpacific.gui.server.customDataSource; import java.util.HashMap; import java.util.Map; import com.isomorphic.datasource.DSRequest; import com.isomorphic.datasource.DSResponse; public class BenchmarkDS extends IpDataSource { @Override public DSResponse executeCustom(DSRequest req) throws Exception { int howMany = 500; DSResponse response = new DSResponse(); String responseString = ""; long time = System.currentTimeMillis(); DSRequest removeReq = newRequestInContext(req, "benchmark", OP_REMOVE); removeReq.setCriteria("field6", "value_6"); DSResponse removeResp = removeReq.execute(); time = System.currentTimeMillis() - time; responseString += "<br/>Total time to delete "+removeResp.getAffectedRows()+" records was " + time + " milliseconds"; time = System.currentTimeMillis(); for (int i=0; i<howMany; i++) { DSRequest addReq = newRequestInContext(req, "benchmark", OP_ADD); HashMap addRec = new HashMap(); addRec.put("field1", "value_"+i); addRec.put("field2", "value_"+i); addRec.put("field3", "value_"+i); addRec.put("field4", "value_"+i); addRec.put("field5", "value_"+i); addRec.put("field6", "value_6"); addReq.forceInvalidateCache(true); addReq.setValues(addRec); addReq.execute(); } time = System.currentTimeMillis() - time; responseString += "<br/>Total time to insert "+howMany+" records was " + time + " milliseconds"; time = System.currentTimeMillis(); for (int i=0; i<howMany; i++) { DSRequest fetchReq = newRequestInContext(req, "benchmark", OP_FETCH); HashMap criteria = new HashMap(); criteria.put("field1", "value_"+i); criteria.put("field2", "value_"+i); fetchReq.setCriteria(criteria); DSResponse fetchResp = fetchReq.execute(); Map rec = fetchResp.getDataMap(); rec.put("field3", "update_"+i); rec.put("field4", "update_"+i); rec.put("field5", "update_"+i); DSRequest updateReq = newRequestInContext(req, "benchmark", OP_UPDATE); updateReq.setCriteria("id", rec.get("id")); updateReq.setValues(rec); updateReq.forceInvalidateCache(true); updateReq.execute(); } time = System.currentTimeMillis() - time; responseString += "<br/>Total time to fetch/update "+howMany+" records was " + time + " milliseconds"; response.setData(responseString); return response; } }
Code:
protected static DSRequest newRequestInContext(DSRequest req, String dataSource, String operationType) { DSRequest theRequest; theRequest = new DSRequest(dataSource, operationType); theRequest.context = req.context; theRequest.setRPCManager(req.getRPCManager()); return theRequest; }
Comment