Спящий запрос на производительность - PullRequest
0 голосов
/ 22 февраля 2012

У меня есть таблица, похожая на эту;

@Table
public class Person {

  private String name;
  private String address;
  ...
  private String score;
}

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

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

Какой запрос лучше написать, если я хочу выбрать всех людей, которые существуют? (например, то же имя и адрес). Моя таблица людей может содержать огромное количество людей, и список людей, которых я получаю из другой системы, также большой (новый или с обновленными оценками). Мне нужен запрос, который все о производительности :-).

Я использую Java и Hibernate. Кто-нибудь?

РЕДАКТИРОВАТЬ: окончательный sql, вероятно, будет выглядеть примерно так:

select * from Person where name='Paul' AND address='road1 
OR name='John' AND address='road2'
OR name='Stella' AND address='road3'

и многие другие. Вышеупомянутый sql atleast объясняет, что я хочу.

Ответы [ 2 ]

0 голосов
/ 22 февраля 2012

Если я правильно понимаю, у вас уже есть все ваши "внешние" лица в памяти.

Я бы создал Map<String, ExternalPerson>, содержащий всех ваших внешних лиц, проиндексированных по имени.

Затем я бы попросил keySet() этой карты получить список людей, которых нужно получить из базы данных..

Затем я бы выполнил следующий запрос:

select p from Person p where p.name in (:names)

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

Затем выполните итерацию по результатам запроса.Для каждого найденного человека найдите соответствующего внешнего человека с помощью карты или внешних лиц и обновите счет текущего человека.Затем удалите внешнего человека из карты.

В конце процесса карта содержит внешних людей, которых нет в базе данных, и их необходимо создать.

Если набор людей действительно высокомерный, обязательно используйте query.scroll() вместо query.list() для итерации по людям, и регулярно очищайте и очищайте сеанс, как объяснено в этом разделесправочное руководство , чтобы избежать проблем с памятью.

0 голосов
/ 22 февраля 2012

Одним из способов сделать это является внешнее объединение обеих таблиц и составление списка всех людей, которых не существует на стороне. как это (TSQL):

SELECT left.* from db1.owner.persons left LEFT JOIN db2.owner.persons right ON left.name=right.name AND left.address=right.address WHERE right.id IS NULL 

Затем вы можете использовать метод CreateSQLQuery ISession для получения списка людей.

в C # мы пишем это так

var list=session.CreateSQLQuery(queryString,"left",new []{typeof(Person)}).List();

но я не думаю, что это сильно отличается в Java

Если вы хотите повысить производительность по этому запросу, возможно, необходимо поместить несколько индексов в каждую таблицу (например, по имени и адресу)

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