title: Why does Google Cloud SQL (using JDBC) take longer to insert records from Google App Engine than from my personal computer?
body: <p>I can insert 2000 records in 3.5 seconds from my computer, GAE take 14.0 seconds to do the same thing. I cannot see how I can get the Google Driver to use the rewriteBatchedStatements setting.</p>
  
  <p>Here is my relevant Java code:</p>
  
  <pre><code>package year2016.tax8949.database2;
  
  import java.sql.Connection;
  import java.sql.DriverManager;
  import java.sql.PreparedStatement;
  import java.sql.SQLException;
  import java.util.List;
  import java.util.Properties;
  import java.util.logging.Logger;
  
  public class Form89492016TableInserter {
  
  private static final Logger log 
      = Logger.getLogger( "Form89492016TableInserter" );
  
  protected static final String USERNAME = "xxxx";
  
  protected static final String PASSWORD = "xxxxx";
  
  protected static final String INSTANCE_CONNECTION_NAME 
      = "xxxx:us-central1:xxxxx";
  
  protected static final String DB_NAME = "xxxxxx";
  
  protected static final String IP_ADDRESS = "xxx.1xx.2xx.4x";
  
  protected static final String SQL_INSERT 
      = "INSERT into Forms1099B ( orderNumber,acctId,qty,secDesc,dateAcq,dateSold,salesPrice,cost,basisAdj,washAdj,nomineeAdj,otherAdj,term,basisRep,rep1099B,tranType,dateAcqVar,covered,symbol,expired ) VALUES ( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? )";
  
  
  // Whether connecting from Google App Engine
  private boolean fromGAE = false;
  
  // JDBC connection
  private Connection conn = null;
  
  public Form89492016TableInserter( boolean fromGAE ) {
      this.fromGAE = fromGAE;
  }
  
  public void insertBatch( List&lt;Forms1099BRecordBean&gt; records ) {
  
      int batchSize = 500;
  
      insertBatchUsingSize( records, batchSize );
  }
  
  public void insertBatchUsingSize( List&lt;Forms1099BRecordBean&gt; records, 
                                    int batchSize ) {
  
      try {
  
          initializeConnection( );
  
          doInsertions( records, batchSize );
  
          closeConnection( );
  
      }
      catch( SQLException e ) {
          log.severe( e.getMessage( ) );
      }
  
  }
  
  public void closeConnection( ) throws SQLException {
  
      if ( conn != null ) { 
          conn.close( ); 
      } 
  
  }
  
  public void initializeConnection( ) throws SQLException {
  
      String driverName 
          = ( fromGAE ) ? "com.mysql.jdbc.GoogleDriver" : 
                          "com.mysql.jdbc.Driver";
  
      try {
          Class.forName( driverName );
      }
      catch( ClassNotFoundException e ) {
          log.severe( e.getMessage( ) );
          return;
      }
  
      if ( fromGAE ) {
  
          String connectionString 
              = String.format( 
                   "jdbc:google:mysql://%s/%s?user=root&amp;password=%s", 
                   INSTANCE_CONNECTION_NAME, 
                   DB_NAME, 
                   PASSWORD );
  
          conn = DriverManager.getConnection( connectionString );
  
      }
      else {
  
          String url = String.format( "jdbc:mysql://%s:3306/%s",
                                      IP_ADDRESS,
                                      DB_NAME );
  
          Properties props = new Properties();
          props.setProperty( "user", USERNAME );
          props.setProperty( "password", PASSWORD );
          props.setProperty( "rewriteBatchedStatements", "true" );
  
          conn = DriverManager.getConnection( url, props );    
  
      }
  
  }
  
  private void doInsertions( List&lt;Forms1099BRecordBean&gt; records,
                             int batchSize ) throws SQLException {
  
      try ( PreparedStatement stmt = conn.prepareStatement( SQL_INSERT ) ) {
  
          for (int i = 0; i &lt; records.size( ); i++) {
  
              Forms1099BRecordBean item = records.get( i );
  
              stmt.setString( 1, item.getOrderNumber() ); 
              stmt.setString( 2, item.getAcctId() ); 
              stmt.setString( 3, item.getQty() ); 
              stmt.setString( 4, item.getSecDesc() ); 
              stmt.setDate( 5, item.getDateAcq() ); 
              stmt.setDate( 6, item.getDateSold() ); 
              stmt.setBigDecimal( 7, item.getSalesPrice() ); 
              stmt.setBigDecimal( 8, item.getCost() ); 
              stmt.setBigDecimal( 9, item.getBasisAdj() ); 
              stmt.setBigDecimal( 10, item.getWashAdj() ); 
              stmt.setBigDecimal( 11, item.getNomineeAdj() ); 
              stmt.setBigDecimal( 12, item.getOtherAdj() ); 
              stmt.setString( 13, item.getTerm() ); 
              stmt.setString( 14, item.getBasisRep() ); 
              stmt.setString( 15, item.getRep1099B() ); 
              stmt.setString( 16, item.getTranType() ); 
              stmt.setString( 17, item.getDateAcqVar() ); 
              stmt.setString( 18, item.getCovered() ); 
              stmt.setString( 19, item.getSymbol() ); 
              stmt.setString( 20, item.getExpired() ); 
  
              stmt.addBatch( );
  
              // Execute every N items.
              if ( (i + 1) % batchSize == 0 ) {
                  stmt.executeBatch( );     
              }
  
          }
  
          stmt.executeBatch( );
  
      }
  
  }
  
  }
  </code></pre>