Как узнать, кэшируются ли подготовленные заявления? - PullRequest
6 голосов
/ 24 мая 2019

Я использую Hikari с SQL Server 2016 и sqljdbc4-2.0.jar в папке lib tomcat.

Моя конфигурация для ресурса БД выглядит следующим образом:

<Resource name="jdbc/SQLServerDS" auth="Container" type="javax.sql.DataSource"
              username="uname"
              password="pwd"
              driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
              url="jdbc:sqlserver://server:port;DatabaseName=dbName"
              maxActive="20"
              maxIdle="10"
              validationQuery="select 1" />

Моя конфигурация источника данных выглядит следующим образом:

@Bean(name = "dataSource")
    public DataSource getDataSource() throws NamingException {
        HikariConfig config = new HikariConfig();
        config.setMaximumPoolSize(20);
        config.setDataSourceJNDI("java:comp/env/jdbc/SQLServerDS");
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        config.addDataSourceProperty("useServerPrepStmts", "true");
        config.addDataSourceProperty("cacheResultSetMetadata", "true");
        config.addDataSourceProperty("useLocalSessionState", "true");
        config.addDataSourceProperty("cacheServerConfiguration", "true");
        config.addDataSourceProperty("elideSetAutoCommits", "true");
        config.addDataSourceProperty("maintainTimeStats", "false");
        return new TransactionAwareDataSourceProxy(
                new LazyConnectionDataSourceProxy(new HikariDataSource(config)));
    }

Как узнать, работает ли кэширование подготовленного заявления для разных соединений?

Я использую управляемые контейнером пружины транзакции с hibernate v4.3.10.Final.

Кроме того, чтобы кеширование работало, нужно ли включать кэш второго уровня?

1 Ответ

3 голосов
/ 28 мая 2019

HikariCP фактически не поддерживает кэширование PreparedStatement

другие предлагают кэширование PreparedStatement.HikariCP нет.Почему?

Это считается неправильной реализацией

Использование кэша операторов на уровне пула является анти-паттерном и отрицательно повлияет на производительность вашего приложения по сравнению с драйвером.caches.

Объяснение:

На уровне пула соединений PreparedStatements можно кэшировать только для каждого соединения.Если ваше приложение имеет 250 часто выполняемых запросов и пул из 20 соединений, вы просите вашу базу данных хранить до 5000 планов выполнения запросов - и аналогичным образом пул должен кэшировать это множество PreparedStatements и связанный с ним граф объектов.

Большинство основных драйверов JDBC для баз данных уже имеют кэш операторов, который можно настроить, включая PostgreSQL, Oracle, Derby, MySQL, DB2 и многие другие.Драйверы JDBC находятся в уникальном положении для использования специфических функций базы данных, и почти все реализации кэширования способны совместно использовать планы выполнения между соединениями.Это означает, что вместо 5000 операторов в памяти и связанных планов выполнения ваши 250 часто выполняемых запросов приводят к точности 250 планам выполнения в базе данных.Умные реализации даже не сохраняют объекты PreparedStatement в памяти на уровне драйвера, а вместо этого просто присоединяют новые экземпляры к существующим идентификаторам планов.

Если вы принимаете это, вы не должны пытаться \ ожидать кеширования PreparedStatement

Если вы отклоните его, вы можете использовать C3P0 в качестве пула соединений

О Кэш второго уровня в спящем режиме , он в основном не определен впул соединений, но используйте соответствующий провайдер соединений:

HikariCP теперь имеет ConnectionProvider для Hibernate 4.x, называемый HikariConnectionProvider

Чтобы использовать HikariConnectionProvider в Hibernate 4.x, добавьте следующеесвойство вашего файла конфигурации hibernate.properties:

hibernate.connection.provider_class=com.zaxxer.hikari.hibernate.HikariConnectionProvider

Начиная с Hibernate 4.3.6, существует официальный класс ConnectionProvider из Hibernate, который следует использовать вместо реализации HikariCP.Класс называется org.hibernate.hikaricp.internal.HikariCPConnectionProvider

...