Я подключаюсь к базе данных MySQL (InnoDB) через соединение с довольно высокой задержкой (~ 80 мс), но относительно высокой пропускной способностью.
Я заметил, что время запроса значительно варьируется в зависимости от того, как запрос был выдан. В следующих примерах я выполняю запрос для одной маленькой строки по первичному ключу. Время запроса:
- Клиент командной строки (
mysql
): ~ 160 мс
- Сырой JDBC: ~ 240 мс
- Hibernate: ~ 400 мс (начало ~ 0 мс, получение ~ 160 мс, фиксация ~ 240 мс)
- Hibernate, L2: ~ 240 мс (начало ~ 0 мс, получение ~ 0 мс, фиксация ~ 240 мс)
- Hibernate, c3p0: ~ 880 мс (начало ~ 160 мс, получение ~ 240 мс, фиксация ~ 480 мс)
- Hibernate, L2 + c3p0: ~ 640 мс (начало ~ 160 мс, получение ~ 0 мс, фиксация ~ 480 мс)
(«L2» означает, что кэширование Hibernate второго уровня было включено, «c3p0» означает, что c3p0 было включено, «begin», «get» и «commit» - это временные интервалы для различных суб-методов, вызываемых во время запроса) *
Это, примерно, результаты "устойчивого состояния", поэтому кэш L2 горячий, а время запуска Hibernate игнорируется. Я предполагаю, что "get" обычно равен 0 мс, когда кэш L2 включен, потому что фактически не выдается get.
Мои вопросы:
- Почему все запросы так много кратны задержке сети? Кажется, что даже клиент командной строки
mysql
требует двух циклов для простого запроса.
- Почему все запросы JDBC / Hibernate намного медленнее, чем клиент командной строки? Кажется, что даже сырой JDBC-клиент требует трех циклов.
- Почему c3p0, кажется, делает все хуже? Насколько я могу судить, я отключил тестирование соединения, которое иначе могло бы объяснить ситуацию.