У нас есть большой набор данных (объемных данных), которые необходимо проверить, если запись существует в базе данных.
Мы используем SQL Server2012/JPA/Hibernate/Spring.
Что было бы эффективным или рекомендуемым способом проверить, существует ли запись в базе данных?
Наши объекты ProductCodes имеют следующие поля:
private Integer productCodeId // this is the PK
private Integer refCode1 // ref code 1-5 has a unique constraint
private Integer refCode2
private Integer refCode3
private Integer refCode4
private Integer refCode5
... other fields
Службе, которую мы создаем, будет предоставлен файл, где каждая строка представляет собой комбинацию refCode1-5.
Задача службы - проверить и сообщить все строки в файле, который уже существует в базе данных.
Мы смотрим на это с двух сторон.
Подход1: Обычный подход.
//psuedo code for each line in the file call dao. pass the refCode1-5 to query (select * from ProductCodes where refCode1=? and refCode2=? and refCode3=? and refCode4=? and refCode5=?
Подход2: запрос всех записей в подходе БД
Петля, хотя каждая строка в файле, проверяющая хэш-карту
Мы считаем, что это более эффективно с точки зрения подключения к БД, поскольку он не будет создавать 1000 подключений к БД. Однако, если таблица DB имеет, например, 5000 записей, то hibernate/jpa создаст 5000 объектов в памяти и, возможно, сбой приложения
Мы думаем идти на первый подход, поскольку refCode1-5 имеет уникальное ограничение и получит выгоду от неявного индекса.
Но есть ли лучший способ приблизиться к этой проблеме, кроме первого подхода?
Вы можете попробовать использовать оператор concat.
select <your cols> from <your table> where concat(refCode1, refCode2, refCode3, refCode4, refCode5) IN (<set of concatenation from your file>);
Я думаю, что это будет очень эффективно, и может быть стоит попробовать, если предварительно сортировать линии и играть с количеством сцепленных приемов, каждый раз приносит вам некоторые преимущества.
Я предлагаю вам создать временную таблицу в вашем приложении, где сначала хранятся все записи из файла с сохранением пакета, а затем вы запускаете запрос, соединяющий новую таблицу temp и таблицу продуктов, чтобы получить фильтрацию, как вам нравится. Таким образом, вы не блокируете таблицу ProductCodes много раз, чтобы проверять отдельные строки, поскольку SqlServer блокирует строки в инструкции select.
попробуйте что-то вроде оператора выбора партии для 100 refCodes вместо того, чтобы делать один выбор для каждого refCode.
построить запрос типа
select <what ever you want> from <table> where ref_code in (.....)
Постройте выбранную проекцию таким образом, чтобы она не просто давала вам нужную вам информацию, а также детали ref_code. В коде вы можете делать подсчет или многопоточное сканирование результатов, если БД говорит, что у вас меньше refCodes, что число, которое вы кодовое вводите в запрос.
(select * from ProductCodes where refCode1=? and refCode2=? and refCode3=? and refCode4=? and refCode5=?)