I am designing a MySQL database which needs to handle about 600 row inserts per second across various InnoDB tables. My current implementation uses non-batched prepared statements. However, writing to the MySQL database bottlenecks and my queue size increases over time.
The implementation is written in Java, I don’t know the version off hand. It uses MySQL‘s Java connector. I need to look into switching to JDBC tomorrow. I am assuming these are two different connector packages.
I have read the following threads on the issue:
- Optimizing MySQL inserts to handle a data stream
- MyISAM versus InnoDB
- Inserting Binary data into MySQL (without PreparedStatement's)
and from the mysql site:
My questions are:
-
Does anyone have advice or experience on performance differences using INSERTs with prepared statements in batch mode vs. using a single
INSERTstatement with multiple VALUEs. -
What are the performance differences between the
MySQLJava connector vs.JDBC. Should I be using one or the other? -
The tables are for archive purposes, and will see ~90% write to ~10% read (maybe even less). I am using InnoDB. Is this the right choice over MyISAM?
Thank you in advance for your help.
JDBC is simply a Java SE standard of database access offering the standard interfaces so you’re not really bound to a specific JDBC implementation. MySQL Java connector (Connector/J) is an implementation of the JDBC interfaces for MySQL databases only. Out of experience, I’m involved to a project that uses huge amount of data using MySQL, and we mostly prefer MyISAM for data that can be generated: it allows to achieve much higher performance losing transactions, but generally speaking, MyISAM is faster, but InnoDB is more reliable.
I wondered for the performance of the INSERT statements too about a year ago, and found the following old testing code in my code shelf (sorry, it’s a bit complex and a bit out of your question scope). The code below contains examples of 4 ways of inserting the test data:
INSERTs;INSERTs;INSERT(never use it – it’s dangerous);INSERT).It uses TestNG as the runner, and uses some custom code legacy like:
runWithConnection()method – ensures that the connection is closed or put back to the connection pool after the callback is executed (but the code below uses not reliable strategy of the statement closing – even withouttry/finallyto reduce the code);IUnsafeIn<T, E extends Throwable>– a custom callback interface for the methods accepting a single parameter but potentially throwing an exception of type E, like:void handle(T argument) throws E;.Take a look at the methods annotated with the @Test annotation: they actually execute the
INSERTstatements. Also please take a look at theCREATE_TABLE_QUERYconstant: in the source code it uses InnoDB producing the following results at my machine with MySQL 5.5 installed (MySQL Connector/J 5.1.12):If you change the
CREATE_TABLE_QUERYInnoDB to MyISAM, you’d see significant performance increase:Hope this helps.
UPD:
For the 4th way you must properly customize the
max_allowed_packetinmysql.ini(the[mysqld]section) to be large enough to support really big packets.