Java MySQL Hibernate медленный выбор запросов - PullRequest
1 голос
/ 13 марта 2012

У меня есть таблица MySQL для сохранения некоторых объектов Java и я использую Hibernate для отображения данных / столбцов.Объекты / таблица содержат около 50 столбцов / полей.На поверхности и при минимальной загрузке это работает нормально, но у меня возникли проблемы при запуске программы, когда я загружаю все доступные объекты из таблицы.В настоящее время в таблице около 8500 строк.Загрузка этих рядов занимает мучительно долго, более 5 минут!Очевидно, что это неправильно, и я, должно быть, сделал что-то ужасно неправильное в моей конфигурации Hibernate (или в другом месте).Обычный запрос для всех строк, использующий пакет java.sql. *, Занимает около 300 мсек, чтобы получить 8000+ строк, что приемлемо, но в идеале я хотел бы сохранить Hibernate из-за его функций отображения.

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

<hibernate-configuration>
<session-factory>
  <property name="hibernate.connection.driver_class">
    com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.url">

jdbc:mysql://127.0.0.1:3306/abc</property>
  <property name="hibernate.connection.username">user</property>
  <property name="hibernate.connection.password">password</property>

  <property name="org.hibernate.SQL">true</property>
  <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="hibernate.hbm2ddl.auto">update</property>

  <property name="hibernate.c3p0.idle_test_period">60</property>
  <property name="hibernate.c3p0.min_size">5</property>
  <property name="hibernate.c3p0.max_size">20</property>
  <property name="hibernate.c3p0.max_statements">250</property>
  <property name="hibernate.c3p0.timeout">1800</property>
  <property name="hibernate.c3p0.acquireRetryAttempts">1</property>
  <property name="hibernate.c3p0.acquireRetryDelay">250</property>

  <property name= "hibernate.transaction.factory_class">
      org.hibernate.transaction.JDBCTransactionFactory
  </property>
  <property name="hibernate.current_session_context_class">thread</property>

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

Очевидно, что я не специалист по Hibernate, поэтому я очень признателен за понимание того, что я делаю неправильно.Спасибо.

UPDATE1 Добавление вывода журнала из запросов.

20:16:40,633 DEBUG QueryTranslatorImpl:283 - --- HQL AST ---
     \-[QUERY] Node: 'query'
        +-[SELECT_FROM] Node: 'SELECT_FROM'
        |  \-[FROM] Node: 'from'
        |     \-[RANGE] Node: 'RANGE'
        |        \-[DOT] Node: '.'
        |           +-[DOT] Node: '.'
        |           |  +-[DOT] Node: '.'
        |           |  |  +-[DOT] Node: '.'
        |           |  |  |  +-[IDENT] Node: 'com'
        |           |  |  |  \-[IDENT] Node: 'xyz'
        |           |  |  \-[IDENT] Node: 'objects'
        |           |  \-[IDENT] Node: 'abc'
        |           \-[IDENT] Node: 'ObjectID'
        \-[WHERE] Node: 'where'
           \-[EQ] Node: '='
              +-[IDENT] Node: 'event_id'
              \-[NUM_INT] Node: '1331570489282'

20:16:40,633 DEBUG QueryTranslatorImpl:252 - --- SQL AST ---
 \-[SELECT] QueryNode: 'SELECT'  querySpaces (order_log)
    +-[SELECT_CLAUSE] SelectClause: '{derived select clause}'
    |  +-[SELECT_EXPR] SelectExpressionImpl: 'objectid0_.event_id as abc1_0_' {FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=null,role=null,tableName=order_log,tableAlias=objectid0_,origin=null,columns={,className=com.xyz.objects.abc.objectid}}}
    |  \-[SQL_TOKEN] SqlFragment: 'objectid0_.order_id as abc2_0_, objectid0_.order_id as order3_0_, objectid0_.px_cond as px4_0_, objectid0_.px_curr as px5_0_, objectid0_.px_value as px6_0_, objectid0_.vol_cond as vol7_0_, objectid0_.vol as vol0_, objectid0_.side as side0_, objectid0_.trd_vol as trd10_0_, objectid0_.open_vol as open11_0_, objectid0_.accno as accno0_, objectid0_.symbol as symbol0_, objectid0_.market as market0_, objectid0_.validity_type as validity15_0_, objectid0_.validity_date as validity16_0_, objectid0_.mod_date as mod17_0_, objectid0_.result_code as result18_0_, objectid0_.order_state as order19_0_, objectid0_.action_state as action20_0_, objectid0_.action_type as action21_0_, objectid0_.action_status as action22_0_, objectid0_.status_text as status23_0_, objectid0_.strategy_id as strategy24_0_, objectid0_.passive as passive0_, objectid0_.timestamp as timestamp0_, objectid0_.confirmedorder as confirm27_0_, objectid0_.updatesource as updates28_0_'
    +-[FROM] FromClause: 'from' FromClause{level=1, fromElementCounter=1, fromElements=1, fromElementByClassAlias=[], fromElementByTableAlias=[objectid0_], fromElementsByPath=[], collectionJoinFromElementsByPath=[], impliedElements=[]}
    |  \-[FROM_FRAGMENT] FromElement: 'order_log objectid0_' FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=null,role=null,tableName=order_log,tableAlias=objectid0_,origin=null,columns={,className=com.abc.objects.xyz.objectid}}
    \-[WHERE] SqlNode: 'where'
       \-[EQ] BinaryLogicOperatorNode: '='
          +-[IDENT] IdentNode: 'event_id' {originalText=event_id}
          \-[NUM_INT] LiteralNode: '1331570489282'

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

UPDATE2 Добавление фактического вывода sql.

Hibernate: /* from objectid where abc_event_id=1331570505614 */ select objectid0
_.abc_event_id as abc1_0_, objectid0_.abc_order_id as abc2_0_, objectid0_.
order_id as order3_0_, objectid0_.px_cond as px4_0_, objectid0_.px_curr as px5_0_,
 objectid0_.px_value as px6_0_, objectid0_.vol_cond as vol7_0_, objectid0_.vol as v
ol0_, objectid0_.side as side0_, objectid0_.trd_vol as trd10_0_, objectid0_.open_vo
l as open11_0_, objectid0_.accno as accno0_, objectid0_.symbol as symbol0_, ucorde
r0_.market as market0_, objectid0_.validity_type as validity15_0_, objectid0_.vali
dity_date as validity16_0_, objectid0_.mod_date as mod17_0_, objectid0_.result_cod
e as result18_0_, objectid0_.order_state as order19_0_, objectid0_.action_state as
 action20_0_, objectid0_.action_type as action21_0_, objectid0_.action_status as a
ction22_0_, objectid0_.status_text as status23_0_, objectid0_.strategy_id as strat
egy24_0_, objectid0_.passive as passive0_, objectid0_.timestamp as timestamp0_, uc
order0_.confirmedorder as confirm27_0_, objectid0_.updatesource as updates28_0_ f
rom order_log objectid0_ where abc_event_id=1331570505614

UPDATE 3 ObjectОтображение + код транзакции

<hibernate-mapping>
  <class name="com.abc.objects.xyz.objectid" table="order_log">
   <id name="EventId" type="long" column="event_id" >
   <generator class="assigned"/>
  </id>

  <property name="ordId">
    <column name="order_id"/>
  </property>
  <property name="pxCond">
    <column name="px_cond"/>
  </property>
...
</hibernate-mapping>

Отображение является выдержкой, но оно прямо по тем же линиям, что и выше.Транзакция, которая запрашивает таблицу, выглядит следующим образом:

Session session = HibernateUtil.getSessionFactory().openSession();
org.hibernate.Transaction transaction = null;
try {
   long t0 = System.currentTimeMillis();
   transaction = session.beginTransaction();
   List<UCOrder> result = session.createQuery("from UCOrder").list();
   transaction.commit();
   System.out.println (result.size() + " rows were retrieved");
   System.out.println("Time elapsed: " + (System.currentTimeMillis()-t0));
} catch (Exception e) {
   transaction.rollback();
   e.printStackTrace();
} finally {
   session.close();
}

Также довольно просто, я хотел бы подумать?!?.Однако время, необходимое для извлечения данных, в тысячу раз больше, чем ванильный метод java.sql.*, показанный ниже:

Connection conn = DriverManager.getConnection (url, userName, password);
Statement s = conn.createStatement ();
s.executeQuery ("SELECT * FROM order_log");
ResultSet rs = s.getResultSet ();

Ответы [ 2 ]

1 голос
/ 13 марта 2012

Я предлагаю вам включить подробное ведение журнала в Hibernate.Вы можете заставить его регистрировать все запросы SQL и видеть, есть ли в них что-то необычное.

Один из способов сделать это - установить hibernate.show_sql в true и / или (?) Настроить использование ведения общего журнала.Hibernate для вывода всех категорий org.hibernate в ваш любимый выходной файл.

0 голосов
/ 19 мая 2016

Вам не нужно транзакции в "выберите". если вы используете log4j, пожалуйста, отключите отладку для спящего режима. Подать заявку на сопоставление таблицы «режим ленивый». Это очень важно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...