2017-11-16 1 views
1

TL; DRApache Drill „Grenze 0“ Abfrage während Frühling Datenquelle mit

Ich habe einen Frühling Boot-Anwendung, die auf dem Dateisystem gespeichert Verwendung von Parkett-Dateien macht. Um darauf zuzugreifen, verwenden wir Apache Drill.

Da ich auf mehrere Benutzer zugreifen kann, habe ich im Frühling einen Verbindungspool eingerichtet.

Wenn ich den Verbindungspool verwende, führt Drill irgendwie eine "Limit 0" -Abfrage aus, bevor meine eigentliche Abfrage ausgeführt wird, und dies beeinträchtigt die Leistung. Die gleiche "limit 0" -Abfrage wird NICHT ausgeführt, wenn ich meine Abfragen über eine einfache Anweisung aus der direkten Verbindung ausführe.

Dies scheint mit der Tatsache verwandt zu sein, dass Spring JdbcTemplate PreparedStatements anstelle von einfachen Anweisungen verwendet.

Gibt es eine Möglichkeit, diese "Grenze 0" -Abfragen loszuwerden?

- Einzelheiten -

Der Verbindungspool in der Spring-Konfigurationsklasse wie folgt aussieht:

@Bean 
@ConfigurationProperties(prefix = "datasource.parquet") 
@Qualifier("parquetDataSource") 
public DataSource parquetDataSource() { 
    return DataSourceBuilder.create().build(); 
} 

und die entsprechenden Eigenschaften in der Entwicklung Profil YML Datei sind:

datasource: 
    parquet: 
    url: jdbc:drill:drillbit=localhost:31010 
    jdbcUrl: jdbc:drill:drillbit=localhost:31010 
    jndiName: jdbc/app_parquet 
    driverClassName: org.apache.drill.jdbc.Driver 
    maximumPoolSize: 5 
    initialSize: 1 
    maxIdle: 10 
    maxActive: 20 
    validation-query: SELECT 1 FROM sys.version 
    test-on-borrow: true 

Wenn ich eine Abfrage mit dem JdbcTemplate, das mit der erwähnten Drill-DataSource erstellt wurde, 3 verschiedene q ueries könnte ausgeführt werden:

  1. die Validierungsabfrage SELECT 1 FROM sys.version;
  2. eine "Grenze 0" Abfrage, die aussieht wie SELECT * FROM (<my actual query>) LIMIT 0;
  3. meine eigentliche Abfrage.

Hier ist der Ausführungscode (parquetJdbcTemplate ist eine Instanz einer Klasse, die org.springframework.jdbc.core.JdbcTemplate erstreckt):

parquetJdbcTemplate.query(sqlQuery, namedParameters, 
      resultSet -> { 
       MyResultSet result = new MyResultSet(); 
       while (resultSet.next()) { 
        // populate the "result" object 
       } 
       return result; 
      }); 

Hier ist ein Screenshot von der Profilseite von meinem Drill-Monitor:

Die untere Abfrage ist die "Grenze 0", dann in der Mitte haben Sie die Validierung Abfrage und oben (auch wenn die Abfrage nicht angezeigt wird) die eigentliche Abfrage, die die Daten zurückgibt, die ich möchte.

Wie Sie sehen können, dauert die Abfrage "limit 0" mehr als 1/3 der gesamten Ausführungszeit. Die Validierungsabfrage ist in Ordnung, da die Ausführungszeit vernachlässigbar ist und zur Überprüfung der Verbindung benötigt wird.

Die Tatsache ist, wenn ich die gleiche Abfrage mit einer Verbindung durch die Drill-Treiber (also ohne Pool) ausführen, ich habe nur meine eigentliche Abfrage im UI-Monitor sehen:

public void executeQuery(String myQuery) { 
    Class.forName("org.apache.drill.jdbc.Driver"); 
    Driver.load(); 
    Connection connection = DriverManager.getConnection("jdbc:drill:drillbit=localhost:31010"); 
    Statement st = connection.createStatement(); 
    ResultSet resultSet = st.executeQuery(myQuery); 
    while (resultSet.next()) { 
     // do stuff 
    } 
} 

monitor screenshot Wie Sie können sehen, die Gesamtausführungszeit wird um einiges verbessert (~ 14 Sekunden statt ~ 26), nur weil die Abfrage "Limit 0" nicht ausgeführt wird.

Soweit ich weiß, werden diese Abfragen "limit 0" ausgeführt, um Informationen über das zugrundeliegende Schema der Parkettdateien zu validieren und zu erhalten. Gibt es eine Möglichkeit, sie bei Verwendung des Verbindungspools zu deaktivieren? Ich möchte PreparedStatements idealerweise immer noch über einfache Statements verwenden, aber ich könnte bei Bedarf zu einfachen Statements wechseln, da ich die volle Kontrolle über diese Abfragen habe (also sollte keine SQL-Injektion möglich sein, solange nicht jemand die bereitgestellten Artefakte hackt).

Antwort

1

Sie haben Recht. Drill führt Limit 0 vorbereiteter Anweisungen aus, um Informationen über das Schema zu erhalten. Ich glaube nicht, dass es eine Möglichkeit gibt, ein solches Verhalten zu verhindern. Obwohl ich empfehlen kann, die Option planner.enable_limit0_optimization zu aktivieren, die standardmäßig falsch ist, kann dies die Ausführung von 0 Abfragen begrenzen. Eine andere Möglichkeit, die Anzahl der Abfragen zu begrenzen, besteht darin, das Schema explizit anzugeben, indem Übersichten über die Verwendung der Ansicht oder direkt in Abfragen verwendet werden.

In Bezug auf keine Abfrage angezeigt, ich denke, das wurde in der neuesten Version von Drill behoben.

+0

Danke für die Antwort. Leider habe ich bereits versucht, 'planner.enable_limit0_optimization' auf' true' zu ​​setzen und Ansichten mit "cast" -Funktionen zu verwenden. Die Gesamtleistung hat sich zwar etwas verbessert, ist aber aufgrund der zusätzlichen "0-Limit" -Abfrage immer noch nicht akzeptabel. Danke auch über die Abfrage nicht angezeigt werden, werde ich meine Drill-Version aktualisieren. – javatutorial