2008-10-21 2 views
8

Как я могу воспользоваться возможностью MySQL кэшировать подготовленные заявления? Одна из причин использования подготовленных операторов состоит в том, что нет необходимости отправлять сам подготовленный оператор несколько раз, если снова использовать тот же подготовленный оператор.Как использовать подготовленное MySQL кэширование инструкции?

Class.forName("com.mysql.jdbc.Driver"); 
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb" + 
     "?cachePrepStmts=true", "user", "pass"); 
for (int i = 0; i < 5; i++) { 
    PreparedStatement ps = conn.prepareStatement("select * from MYTABLE where id=?"); 
    ps.setInt(1, 1); 
    ps.execute(); 
} 
conn.close() 

При выполнении приведенного выше примера Java я вижу 5 пар команд «Подготовка и выполнение» в файле журнала mysqld. Перемещение назначения ps вне цикла приводит к единым командам Prepare и 5 Execute. Параметр подключения "cachePrepStmts = true" здесь не имеет никакого значения.
При запуске аналогичной программы с использованием Spring и Hibernate количество команд Prepare, отправленных (1 или 5), зависит от того, включен ли параметр подключения cachePrepStmts. Как Hibernate выполняет подготовленные инструкции, чтобы воспользоваться настройкой cachePrepStmts? Можно ли имитировать это с помощью чистого JDBC?
я бегу это на сервере MySQL 4.1.22 и MySQL-разъем-Java-5.0.4.jar

ответ

2

Можно ли имитировать это с помощью чистого JDBC?

На самом деле это не то, что вы сделали, переведя подготовленный оператор из цикла?

Возможно, я неправильно понимаю, как работает кеш MySQL, но обязательно ли файл журнала сообщает о работе кеша? Возможно, Spring или Hibernate имеют свой собственный промежуточный кеш, который проверяет подготовленные заявления против отправленных ранее. Возможно, это вы видите, когда запускаете программу с помощью Spring. Это означало бы сделать немного отслеживания с вашей системой, чтобы узнать, только ли журнал mysqld сообщает отчеты, которые он отправил, независимо от того, как они с ними справляются.

2

Вы должны подготовить свое заявление только один раз, вне цикла, а затем привязать параметры в цикле. Вот почему подготовленные операторы имеют параметры привязки, поэтому вы можете повторно использовать подготовленный оператор.

Hibernate делает именно это, рассматривая весь SQL как подготовленный оператор за кулисами, хотя вы, очевидно, можете злоупотреблять этим, если используете литералы, а не параметры привязки.

1

Во-первых, ваше PreparedStatement воссоздается в цикле, поэтому драйвер JDBC может отбрасывать подготовленные данные. Поэтому вы попросили уродливое поведение, и вы получили его.

И затем, PreparedStatement в MySQL - это отдельная глава. Чтобы иметь реальное кэширование, вы должны запросить его явно через свойство соединения.

Таким образом, вы должны установить для свойства cacheXrepStmts значение "true", чтобы получить кеширование готовых операторов. По умолчанию для этого свойства установлено значение false.

@see руководство MySQL для вашей версии MySQL для деталей

1

Вы должны подготовить заявление вне цикла.

Connection conn = DatabaseUtil.getConnection(); 
PreparedStatement stmtUpdate = conn.prepareStatement("UPDATE foo SET bar=? WHERE id = ?"); 
for(int id=0; id<10; id++){ 
    stmtUpdate.setString(1, "baz"); 
    stmtUpdate.setInt(2, id); 
    int rows = stmtUpdate.executeUpdate(); 
    // Clear parameters for reusing the preparedStatement 
    stmtUpdate.clearParameters(); 
} 
conn.close(); 

Я не знаю, о кеширования MySQL подготовленных инструкций, но это путь JDBC подготовлены заявления должны быть повторно использованы.

2

Вам также необходимо установить размер кэша операторов в экземпляре соединения. Я предполагаю, что размер кеша по умолчанию равен 0. Следовательно, ничего не будет кэшироваться.

Смежные вопросы