MySQL Connector C++
-
Hier mal ein kleiner AUsschnitt aus einem Testprogramm der Dokumentation (https://downloads.mysql.com/docs/connector-cpp-1.1-en.a4.pdf, S.26):
driver = get_driver_instance(); con = driver->connect("tcp://127.0.0.1:3306", "root", "root"); /* Connect to the MySQL test database */ con->setSchema("test"); stmt = con->createStatement(); stmt->execute("DROP TABLE IF EXISTS test"); stmt->execute("CREATE TABLE test(id INT)"); delete stmt; /* '?' is the supported placeholder syntax */ pstmt = con->prepareStatement("INSERT INTO test(id) VALUES (?)"); for (int i = 1; i <= 10; i++) { pstmt->setInt(1, i); pstmt->executeUpdate(); } delete pstmt;
Wird hier wirklich pro Schleifendurchgang ein Query an die Datenbank geschickt?
Gibt es eine Möglichkeit mehrere Queries erst zu sammeln, bevor man sie durchführt, also eine Art "commit"?
Ich stelle mir vor, dass es ineffizient ist, evt tausende von kleinen Queries in einer Schleife durchzuführen. Irre ich mich da?
-
@ravenheart_ggg
Das ist keine Query, sondern ein Insert. Wenn das Demoprogramm 10 Zeilen einfügen möchte dann muss sie 10x ein Kommando zur db schicken.
Um Geschwindigkeit zu gewinnen kann man sowas in eine Transaktion verpacken, aber ansonsten ist das so schon ok.
-
Du kannst ja auch
insert into test(id) values (?), (?), (?), ...
ausführen, z.B immer 10 oder 100 auf einmal. Vielleicht ist das effizienter? (Müsste man ausprobieren...)
-
@DocShoe Danke für die Aufklärung. Ich bin kein Datenbank-Experte, weshalb ich vlt ab und an falsche Begrifflichkeiten verwende.
Ich habe jetzt nichts konkretes zu Transaktionen beim mysqlcppconn gefunden.
Anscheinend ist bei der Connection allerdings autocommit standardmäßig aktiviert.
Kann ich mir Laufzeitvorteile erhoffen, wenn ich das deaktiviere und am Ende meiner Inserts ein Commit aufrufe?
-
@ravenheart_ggg
Ich bin kein MySQL Experte, daher kann ich dir nix dazu sagen. Hab grad kurz gegoogelt und das dabei herausgefunden:
MySQL benutzt verschiedene Engines, die man bei der Erzeugung einer Tabelle angeben kann. Die MyISAM Engine ist zB nicht transaktionsfähig, da fallen Transaktionen grundsätzlich weg. Dafür wird sie bei Einzeloperationen auch etwas schneller sein, da Overhead wegfällt. InnoDB ist transaktionsfähig, und da könnte man mal vergleichen. Wie wird die db denn benutzt? Hast du viele einzelne Schreiboperationen, die unabhängig voneinander sind, oder schreibst du viele zusammenhängende Daten? Das kann ein Kriterium für die sinnvollere Engine sein.
Ansonsten hast du recht, viele tausend einzelne Queries sind oft langsamer als eine Query mit einer komplexen where-Klausel.
Und wenn der MySQLConnector keine Transaktionen unterstützt kannste dir das etwa so selber bauen:class MySQLTransaction { Connection* Connection_ = nullptr; public: MySQLTransaction( Connection* conn ) : Connection_( conn ) { start_transaction(); } ~MySQLTransaction() { commit(); } // Kopieren verhinden MySQLTransaction( MySQLTransaction const& ) = delete; MySQLTransaction& operator=( MySQLTransaction const& ) = delete; void start_transaction() { execute( "START TRANSACTION" ); } void commit() { execute( "COMMIT" ); Connection_ = nullptr; } void rollback() { execute( "ROLLBACK" ); } private: void execute( std:.string const& sql ) { if( Connection_ ) { unique_ptr<Statement> stmt( Connection_->createStatement ); stmt->execute( sql ); } } };
-
@wob
Ui, wusste ich noch nicht
-
@DocShoe sagte in MySQL Connector C++:
Ansonsten hast du recht, viele tausend einzelne Queries sind oft langsamer als eine Query mit einer komplexen where-Klausel.
Wobei das nur bis zu einer gewissen grenze stimmt. Wenn das query zu komplex wird ist das auch wieder kontraproduktiv. Da sind dann wieder kleinere einzel queries besser
-
@DocShoe sagte in MySQL Connector C++:
Ansonsten hast du recht, viele tausend einzelne Queries sind oft langsamer als eine Query mit einer komplexen where-Klausel.