Запрос критериев гибернации требует времени для извлечения записей из таблицы базы данных - PullRequest
0 голосов
/ 04 января 2019

В моем проекте я добавляю 10000 записей в таблицу. Если какая-либо запись уже доступна, мы выбираем ее, используя критерии гибернации и сравнивая ее с новой записью. У нас очень мало данных в таблице около 10000 записей. Для критериев гибернации мы применили условия. Этот критерий гибернации выбирает 6 записей из таблицы. Но почему это занимает время, если я вызываю метод attribute.list () для получения 6 записей

Запрос критериев HIbernate:

select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_, 
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_ from FI_SALES_LOCATION_V this_ where (this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000') and this_.DEL_DTIME is null and ((this_.LANG_CODE_ISO='en' and this_.CTY_CODE_ISO='GB' and this_.ID='A1000') or (this_.LANG_CODE_ISO='en' and this_.CTY_CODE_ISO='GB' and this_.ID='AP1000') or (this_.LANG_CODE_ISO='pt' and this_.CTY_CODE_ISO='PT' and this_.ID='AP1000') or (this_.LANG_CODE_ISO='pt' and this_.CTY_CODE_ISO='PT' and this_.ID='A1000') or (this_.LANG_CODE_ISO='s1' and this_.CTY_CODE_ISO='SI' and this_.ID='AP1000') or (this_.LANG_CODE_ISO='s1' and this_.CTY_CODE_ISO='SI' and this_.ID='A1000'));

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Учитывая информацию из вопроса и комментариев, это то, что происходит в вашем коде:

  • Для каждой записи, которую нужно вставить, вы делаете выбор с помощью критериев.
  • Сделайте проверку и, в зависимости от ситуации, вы сохраните или объедините запись.

Вы должны понимать, как сеансы гибернации ведут себя в некоторых ситуациях. Когда вы выполняете операцию в режиме гибернации, то, что вы делаете (в первый момент), обновляет сеанс гибернации. При вставке, удалении или обновлении операция будет выполняться в сеансе, Hibernate даже будет записывать инструкцию SQL, но она не будет немедленно сброшена в вашу БД (да, это вводит в заблуждение) .

Обычно все сбрасывается и завершается транзакция, но в определенных ситуациях hibernate будет сбрасывать операции, чтобы поддерживать сеанс в актуальном состоянии. В вашем случае у вас есть несколько записей для вставки / объединения, но перед каждой операцией вы выполняете выбор. Hibernate обнаруживает эту операцию и сбрасывает каждую ранее сохраненную операцию просто потому, что не имеет смысла запрашивать БД, если есть ожидающие операции, которые необходимо очистить. БД должна быть в самом актуальном состоянии, которое возможно. Не пытайтесь бороться с этим, он предназначен для такой работы.

Так что я думаю, что когда ваш выбор занимает слишком много времени, это происходит потому, что hibernate сбрасывает предыдущую операцию вставки / обновления .

Как это решить:

Я не могу придумать никакого простого способа решить эту проблему. Вам придется пересмотреть свой подход.

Есть одна важная вещь: даже если бы вам нужно было только чистые вставки без какой-либо проверки, у вас были бы некоторые проблемы, потому что ваш код пытается вставить тысячи записей. Большая проблема в том, что, как я писал ранее, hibernate не сбрасывает операции до конца транзакции. Таким образом, он будет хранить в памяти все выполняемые операторы. Есть большая вероятность того, что вам не хватит памяти.

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

Из небольшой доступной информации я бы попробовал этот рабочий процесс:

Прежде всего, определите свойство размера партии для режима гибернации (опять же, проверьте документы при дозировании)

  • При обработке ваших данных возьмите кусочек данных с тем же размером, который определен для размера пакета
  • Сделайте выбор, который выбирает каждую возможную запись для проверки в тех записях, которые должны быть вставлены
  • Выполните необходимые проверки, чтобы проверить, является ли это слияние или вставка для каждой записи в срезе
  • Группирует вставки, объединяет и выполняет операции. Промывка и очистка спящего режима
  • Возьмите следующий фрагмент данных и повторите процесс

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

0 голосов
/ 04 января 2019

Попробуйте написать запрос следующим образом:

select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_, 
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_ 
from FI_SALES_LOCATION_V this_ 
where 
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000') 
and this_.DEL_DTIME is null 
and (this_.LANG_CODE_ISO='en' and this_.CTY_CODE_ISO='GB' and this_.ID='A1000') 
UNION ALL
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_, 
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_ 
from FI_SALES_LOCATION_V this_ 
where 
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000') 
and this_.DEL_DTIME is null 
and (this_.LANG_CODE_ISO='en' and this_.CTY_CODE_ISO='GB' and this_.ID='AP1000') 
UNION ALL
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_, 
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_ 
from FI_SALES_LOCATION_V this_ 
where 
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000') 
and this_.DEL_DTIME is null 
and (this_.LANG_CODE_ISO='pt' and this_.CTY_CODE_ISO='PT' and this_.ID='AP1000') 
UNION ALL
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_, 
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_ 
from FI_SALES_LOCATION_V this_ 
where 
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000') 
and this_.DEL_DTIME is null 
and (this_.LANG_CODE_ISO='pt' and this_.CTY_CODE_ISO='PT' and this_.ID='A1000') 
UNION  ALL
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_, 
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_ 
from FI_SALES_LOCATION_V this_ 
where 
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000') 
and this_.DEL_DTIME is null 
and (this_.LANG_CODE_ISO='s1' and this_.CTY_CODE_ISO='SI' and this_.ID='AP1000') 
UNION ALL
select this_.CLASS_TYPE as CLASS1_15_0_, this_.CLASS_UNIT_TYPE as CLASS2_15_0_, this_.CLASS_UNIT_CODE as CLASS3_15_0_, 
this_.ID as ID15_0_, this_.LANG_CODE_ISO as LANG5_15_0_, this_.CTY_CODE_ISO as CTY6_15_0_, this_.NAME as NAME15_0_, this_.INS_DTIME as INS8_15_0_,this_.UPD_DTIME as UPD9_15_0_, this_.DEL_DTIME as DEL10_15_0_ 
from FI_SALES_LOCATION_V this_ 
where 
(this_.CLASS_TYPE='BU' and this_.CLASS_UNIT_TYPE='STO' and this_.CLASS_UNIT_CODE='A1000') 
and this_.DEL_DTIME is null 
and (this_.LANG_CODE_ISO='s1' and this_.CTY_CODE_ISO='SI' and this_.ID='A1000');

Даже если писать больше, производительность улучшается, когда вы выполняете UNION ALL, а не OR.

Или вы можете проиндексировать таблицу, но при INSERT вы потеряете производительность.

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