mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Fix to use mysqlResultSetOptimization with c3p0-provided connections.
This commit is contained in:
@ -55,6 +55,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
|||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.Pair;
|
import com.kingsrook.qqq.backend.core.utils.Pair;
|
||||||
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
|
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
|
||||||
|
import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData;
|
||||||
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
||||||
|
|
||||||
|
|
||||||
@ -356,18 +357,29 @@ public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterf
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private PreparedStatement createStatement(Connection connection, String sql, QueryInput queryInput) throws SQLException
|
private PreparedStatement createStatement(Connection connection, String sql, QueryInput queryInput) throws SQLException
|
||||||
{
|
{
|
||||||
if(connection.getClass().getName().startsWith("com.mysql"))
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// if we're allowed to use the mysqlResultSetOptimization, and we have //
|
||||||
|
// the query hint of "potentially large no of results", then check if //
|
||||||
|
// our backend is indeed mysql, and if so, then apply those settings. //
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
if(mysqlResultSetOptimizationEnabled && queryInput.hasQueryHint(QueryHint.POTENTIALLY_LARGE_NUMBER_OF_RESULTS))
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
RDBMSBackendMetaData rdbmsBackendMetaData = (RDBMSBackendMetaData) queryInput.getBackend();
|
||||||
// if we're allowed to use the mysqlResultSetOptimization, and we have the query hint of "expected large result set", then do it. //
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
if(mysqlResultSetOptimizationEnabled && queryInput.getQueryHints() != null && queryInput.getQueryHints().contains(QueryHint.POTENTIALLY_LARGE_NUMBER_OF_RESULTS))
|
// todo - remove "aurora" - it's a legacy value here for a staged rollout //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(RDBMSBackendMetaData.VENDOR_MYSQL.equals(rdbmsBackendMetaData.getVendor()) || RDBMSBackendMetaData.VENDOR_AURORA_MYSQL.equals(rdbmsBackendMetaData.getVendor()) || "aurora".equals(rdbmsBackendMetaData.getVendor()))
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// mysql "optimization", presumably here - from Result Set section of https://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html //
|
// mysql "optimization", presumably here - from Result Set section of //
|
||||||
// without this change, we saw ~10 seconds of "wait" time, before results would start to stream out of a large query (e.g., > 1,000,000 rows). //
|
// https://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html without //
|
||||||
// with this change, we start to get results immediately, and the total runtime also seems lower... //
|
// this change, we saw ~10 seconds of "wait" time, before results would start to stream out of a //
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
// large query (e.g., > 1,000,000 rows). //
|
||||||
|
// with this change, we start to get results immediately, and the total runtime also seems lower... //
|
||||||
|
// perhaps more importantly, without this change, the whole result set goes into memory - but with //
|
||||||
|
// this change, it is streamed. //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
PreparedStatement statement = connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
|
PreparedStatement statement = connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
|
||||||
statement.setFetchSize(Integer.MIN_VALUE);
|
statement.setFetchSize(Integer.MIN_VALUE);
|
||||||
return (statement);
|
return (statement);
|
||||||
|
@ -150,8 +150,11 @@ public class ConnectionManager
|
|||||||
|
|
||||||
return switch(backend.getVendor())
|
return switch(backend.getVendor())
|
||||||
{
|
{
|
||||||
case "mysql", "aurora" -> "com.mysql.cj.jdbc.Driver";
|
////////////////////////////////////////////////////////////////////////////
|
||||||
case "h2" -> "org.h2.Driver";
|
// todo - remove "aurora" - it's a legacy value here for a staged rollout //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
case RDBMSBackendMetaData.VENDOR_MYSQL, RDBMSBackendMetaData.VENDOR_AURORA_MYSQL, "aurora" -> "com.mysql.cj.jdbc.Driver";
|
||||||
|
case RDBMSBackendMetaData.VENDOR_H2 -> "org.h2.Driver";
|
||||||
default -> throw (new IllegalStateException("We do not know what jdbc driver to use for vendor name [" + backend.getVendor() + "]. Try setting jdbcDriverClassName in your backend meta data."));
|
default -> throw (new IllegalStateException("We do not know what jdbc driver to use for vendor name [" + backend.getVendor() + "]. Try setting jdbcDriverClassName in your backend meta data."));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -170,11 +173,17 @@ public class ConnectionManager
|
|||||||
|
|
||||||
return switch(backend.getVendor())
|
return switch(backend.getVendor())
|
||||||
{
|
{
|
||||||
// TODO aws-mysql-jdbc driver not working when running on AWS
|
////////////////////////////////////////////////////////////////
|
||||||
|
// TODO aws-mysql-jdbc driver not working when running on AWS //
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
// jdbcURL = "jdbc:mysql:aws://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=CONVERT_TO_NULL";
|
// jdbcURL = "jdbc:mysql:aws://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=CONVERT_TO_NULL";
|
||||||
case "aurora" -> "jdbc:mysql://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&useSSL=false";
|
|
||||||
case "mysql" -> "jdbc:mysql://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull";
|
////////////////////////////////////////////////////////////////////////////
|
||||||
case "h2" -> "jdbc:h2:" + backend.getHostName() + ":" + backend.getDatabaseName() + ";MODE=MySQL;DB_CLOSE_DELAY=-1";
|
// todo - remove "aurora" - it's a legacy value here for a staged rollout //
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
case RDBMSBackendMetaData.VENDOR_AURORA_MYSQL, "aurora" -> "jdbc:mysql://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&useSSL=false";
|
||||||
|
case RDBMSBackendMetaData.VENDOR_MYSQL -> "jdbc:mysql://" + backend.getHostName() + ":" + backend.getPort() + "/" + backend.getDatabaseName() + "?rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull";
|
||||||
|
case RDBMSBackendMetaData.VENDOR_H2 -> "jdbc:h2:" + backend.getHostName() + ":" + backend.getDatabaseName() + ";MODE=MySQL;DB_CLOSE_DELAY=-1";
|
||||||
default -> throw new IllegalArgumentException("Unsupported rdbms backend vendor: " + backend.getVendor());
|
default -> throw new IllegalArgumentException("Unsupported rdbms backend vendor: " + backend.getVendor());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,13 @@ public class RDBMSBackendMetaData extends QBackendMetaData
|
|||||||
|
|
||||||
private RDBMSBackendMetaData readOnlyBackendMetaData;
|
private RDBMSBackendMetaData readOnlyBackendMetaData;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// define well-known (and fully supported) vendor values //
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
public static final String VENDOR_MYSQL = "mysql";
|
||||||
|
public static final String VENDOR_H2 = "h2";
|
||||||
|
public static final String VENDOR_AURORA_MYSQL = "aurora-mysql";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
Reference in New Issue
Block a user