Параметры оптимизации SQL в Java - PullRequest
3 голосов
/ 24 ноября 2010

Допустим, у меня есть базовый запрос, например:

SELECT a, b, c FROM x WHERE y=[Z]

В этом запросе [Z] - это «переменная» с различными значениями, введенными в запрос.ситуация, когда мы хотим выполнить один и тот же запрос с двумя известными различными значениями [Z], скажем Z1 и Z2.Мы можем сделать два отдельных запроса:

SELECT a, b, c FROM x WHERE y=Z1

SELECT a, b, c FROM x WHERE y=Z2

Или, возможно, мы можем программно создать другой запрос, например:

SELECT a, b, c FROM x WHERE y in (Z1, Z2)

Теперь у нас только один запрос (1 <2), ноПостроение запросов и деконструкция набора результатов становятся немного более сложными, поскольку мы больше не делаем простые простые запросы. </p>

Вопросы:

  • Как называется этот вид оптимизации?(Стоит ли это делать?)
  • Как это можно реализовать чисто из Java-приложения?
    • Помогают ли существующие технологии Java ORM?

Ответы [ 5 ]

2 голосов
/ 24 ноября 2010

Как называется этот вид оптимизации?

Я не уверен, что для него есть «правильный» термин, но я слышал, что он называется «пакетная обработка запросов» или «простая группировка».

(стоит ли это делать?)

Это зависит от:

  • стоит ли вообще усилий по оптимизации запроса,
  • количество элементов в наборе; т.е. ... IN ( ... ),
  • накладные расходы на выполнение запроса JDBC по сравнению с затратами на компиляцию запроса и т. Д.

Но при правильных обстоятельствах это определенно стоящая оптимизация.

Как это можно реализовать чисто из Java-приложения?

Это зависит от вашего определения «чистый»: -)

Помогают ли существующие технологии Java ORM?

Это зависит от конкретной технологии ORM, о которой вы говорите, но (например) язык Hibernate HQL поддерживает конструкции, позволяющие вам делать подобные вещи.

0 голосов
/ 25 ноября 2010

Обратите внимание, что «in» (где бла в (1, 5, 10)) - это то же самое, что и «где бла = 1 ИЛИ бла = 5 ИЛИ бла = 10». Это важно, если вы используете, скажем, Apache Torque, который создает прекрасные подготовленные операторы за исключением в случае предложения "in". (Возможно, это уже исправлено.)

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

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

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

0 голосов
/ 25 ноября 2010

Если у вас есть массив или список значений, вы могли бы вручную построить оператор подготовки с использованием JDBC:

// Assuming values is an int[] and conn is a java.sql.Connection
// Also uses Apache Commons StringUtils

StringBuilder query = new StringBuilder("SELECT a, b, c FROM x WHERE y IN (");

query.append(StringUtils.join(Collections.nCopies(values.length, "?"), ',');
query.append(")");

PreparedStatement stmt = conn.prepareStatement(query.toString());

for (int i = 0; i < values.length; i++) {
    stmt.setInt(i + 1, values[i]);
}

stmt.execute();
// Get results after this

Примечание: я на самом деле не проверял это. Теоретически, если бы вы использовали это много, вы бы обобщили это и сделали его методом.

0 голосов
/ 25 ноября 2010

Я, честно говоря, не могу сказать, какой удар (если таковой имеется) вы получите, если выполните эти два Подготовленных запроса (даже используя обычный JDBC ) вместо их объединения с оператором IN.

0 голосов
/ 24 ноября 2010

СУБД может обычно возвращать результат запроса с IN за равное или меньшее время , чем требуется для выполнения двух запросов.

Если в столбце Y нет индекса, требуется полное сканирование таблицы. При двух запросах будет выполнено два сканирования таблицы вместо одного.

Если есть индекс, то одно значение в предложении WHERE или значения в списке IN используются по одному для поиска индекса. Когда для одного из значений в списке IN найдено несколько строк, они добавляются в возвращаемый результат.

Так что лучше использовать предикат IN с точки зрения производительности.

Когда Y представляет столбец с уникальными значениями, результат легко декомпозировать. В противном случае работы немного больше.

...