Im using mysql con JDBC.Ottimizzazione della query MySQL su una tabella di grandi dimensioni
Ho una tabella di esempio di grandi dimensioni che contiene 6,3 milioni di righe su cui sto cercando di eseguire query di selezione efficienti. Vedere di seguito:
ho creato tre indici aggiuntivi sul tavolo, vedere sotto:
Esecuzione di una query SELECT
come questo SELECT latitude, longitude FROM 3dag WHERE timestamp BETWEEN "+startTime+" AND "+endTime+" AND HourOfDay=4 AND DayOfWeek=3"
ha un tempo di esecuzione che è estremamente elevata a 256356 ms, o un po ' più di quattro minuti. Il mio contare sulla stessa query mi dà questo:
Il mio codice per il recupero dei dati è di seguito:
Connection con = null;
PreparedStatement pst = null;
Statement stmt = null;
ResultSet rs = null;
String url = "jdbc:mysql://xxx.xxx.xxx.xx:3306/testdb";
String user = "bigd";
String password = "XXXXX";
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(url, user, password);
String query = "SELECT latitude, longitude FROM 3dag WHERE timestamp BETWEEN "+startTime+" AND "+endTime+" AND HourOfDay=4 AND DayOfWeek=3";
stmt = con.prepareStatement("SELECT latitude, longitude FROM 3dag WHERE timestamp>=" + startTime + " AND timestamp<=" + endTime);
stmt = con.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
rs = stmt.executeQuery(query);
System.out.println("Start");
while (rs.next()) {
int tempLong = (int) ((Double.parseDouble(rs.getString(2))) * 100000);
int x = (int) (maxLong * 100000) - tempLong;
int tempLat = (int) ((Double.parseDouble(rs.getString(1))) * 100000);
int y = (int) (maxLat * 100000) - tempLat;
if (!(y > matrix.length) || !(y < 0) || !(x > matrix[0].length) || !(x < 0)) {
matrix[y][x] += 1;
}
}
System.out.println("End");
JSONObject obj = convertToCRS(matrix);
return obj;
}catch (ClassNotFoundException ex){
Logger lgr = Logger.getLogger(Database.class.getName());
lgr.log(Level.SEVERE, ex.getMessage(), ex);
return null;
}
catch (SQLException ex) {
Logger lgr = Logger.getLogger(Database.class.getName());
lgr.log(Level.SEVERE, ex.getMessage(), ex);
return null;
} finally {
try {
if (rs != null) {
rs.close();
}
if (pst != null) {
pst.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
Logger lgr = Logger.getLogger(Database.class.getName());
lgr.log(Level.WARNING, ex.getMessage(), ex);
return null;
}
}
Rimozione ogni linea nel ciclo while(rs.next())
mi dà la stessa orribile run-time.
La mia domanda è cosa posso fare per ottimizzare questo tipo di query? Sono curioso di sapere lo .setFetchSize()
e quale dovrebbe essere il valore ottimale qui. La documentazione mostra che INTEGER.MIN_VALUE risulta nel recupero riga per riga, è corretto?
Qualsiasi aiuto è apprezzato.
EDIT Dopo la creazione di un nuovo indice sul timestamp, DayOfWeek e HourOfDay mia domanda corre 1 minuto più veloce e spiegare mi dà questo:
Si prega di evitare schermate e mostrare le informazioni in formato testo. È molto più facile leggere e lavorare con. –
Oh, pensavo che sarebbe stato il contrario. Si tratta di una linea guida SO, o semplicemente delle tue preferenze personali? – kongshem
Un motivo è che non è possibile copiare e incollare da un'immagine :-) –