Повторяет выбор или использует предложение IN, что быстрее?

1

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

Скажем, если есть таблица из 50 тысяч записей с полем order_id который правильно проиндексирован. Теперь приложение java имеет список из 500 идентификаторов заказов для поиска сведений о заказе и необходимости присваивать значения каждому объекту заказа. Таким образом, может быть два плана

1. run 500 SELECT queries

for(String id:order_ids){
    Order order = QueryAgent.execute("SELECT * FROM ORDES o WHERE o.order_id ="+id);
    modifyOrder(order);
}

2. run one query whith 500 parameters in 

String orders_in_string = getOrdersInString(order_ids);
List<Order> orders = QueryAgent.execute("SELECT * FROM ORDES o WHERE o.order_id IN ="+orders_in_string);
for(Order order:orders){
    modifyOrder(order);
}

Я не могу сказать, какой из них лучше.

  • 1
    Вы пробовали сравнить два подхода? Запускайте каждый запрос несколько тысяч раз и сколько времени занимает каждый запрос. Тогда вы будете знать, что быстрее.
  • 0
    не создавайте свои строки запроса, добавляя материал. Используйте параметризованные запросы. Читайте о инъекции sql
Теги:
jpa
java-ee

2 ответа

6
Лучший ответ

Два запроса возвратят тот же объем результатов. Итак, ваш реальный вопрос заключается в том, что быстрее: запуск 500 небольших запросов или один большой запрос для получения одинаковых результатов.

Правильный ответ на вопрос о производительности - это побудить вас попробовать его в своей системе и узнать, что быстрее в ваших данных в вашей среде.

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

Если список order_id уже поступает из базы данных, я бы рекомендовал создать более сложный запрос, поэтому им не нужно возвращаться к приложению. Что-то вроде:

select o.*
from orders o
where o.order_id in (select . . . );

Кроме того, если вам не нужны все столбцы, вы должны просто явно выбрать те, которые вы хотите. На самом деле, хорошая идея всегда быть явной в выбранных столбцах.

  • 0
    Это имеет смысл. К сожалению, мы проектируем приложение от JPA, поэтому создание запросов не так гибко. Пример в вопросе - просто демонстрация к делу. Спасибо !
2

Если вы делаете тесты, сначала проверьте, можете ли вы иметь 500 аргументов в инструкции IN. Вторые извлекают только необходимые данные, а третью попробуют подготовить инструкции. Но, если вы случайно можете выбрать базу данных для выбора 500 идентификаторов заказа в одном или двух запросах, попробуйте присоединиться к таблицам или подзапрос данных. Для этого предназначены реляционные базы данных.

  • 4
    Вы можете иметь 500 аргументов, 1000 поддерживаются.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню