2016-02-16 2 views
1

В моем приложении Java я должен выбрать данные из базы данных Oracle с предложением WHERE. Я собираюсь использовать подготовленное заявление. Что лучше, я должен использоватьJDBC Огромные данные для выбора

SELECT column_name FROM table_name WHERE column_name = ? 
SELECT column_name FROM table_name WHERE column_name = ? 
SELECT column_name FROM table_name WHERE column_name = ? 
. 
. 
. 
SELECT column_name FROM table_name WHERE column_name = ? 

или

SELECT column_name FROM table_name WHERE column_name IN (?, ?, ?, ... ?) 

Граф данных мне нужно использовать в ИНЕКЕ может варьироваться от 01 до 500.

ответ

2

Каждое выполнение запроса приходит с некоторая обработка/разбор/сетевые накладные расходы, поэтому на порядок проще получить несколько строк в одном запросе, предоставив список значений в предложении IN. Например, Oracle должен сделать "soft parse" (синтаксическая проверка семантики &, поиск кеша), даже если запрос повторно используется (использует переменные связывания), как это имеет место в первом примере.

Следует отметить, что существует фиксированный предел 1000 переменных привязки, которые вы можете включить в предложение IN в Oracle.

+0

Да, я знаю 1000 предел в разделе IN. Вы знаете лучший способ, чем повторять добавление ',' и '?' в разделе IN, поскольку мои данные для предложения IN находятся в ArrayList? –

+0

[Эта статья] (http://stackoverflow.com/questions/178479/preparedstatement-in-clause-alternatives) имеет несколько альтернатив для динамического генерации запроса с помощью заполнителей привязки. –

0

Если количество возможных значений варьируется от 1 до 500, то, вероятно, не стоит готовить эти 500 запросов. Я бы просто генерировал простой SQL каждый раз (например, SELECT column_name FROM table_name WHERE column_name IN (23,29,31,37)) и выполнял его как простой оператор. Я знаю, что это против правила всегда готовить запросы и использовать привязки (убедитесь, что ваш код не подвержен атакам SQL-инъекций), но правила нарушены.

0

На самом деле оператор in() может быть намного быстрее, но поставляется с (пренебрежимой) стоимостью синтаксического анализа плюс ограничение использования до 500 элементов, а также ограничение общего размера текста запроса sql. Таким образом, это достаточно хорошо, но не является ракетным доказательством :)

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

Вариант перебора здесь http://tkyte.blogspot.hu/2006/06/varying-in-lists.html

Однако, если вы можете использовать PL/SQL, этот беспорядок может стать очень аккуратно.

function getCustomers(in_customerIdList clob) return sys_refcursor is 
begin 
    aux_in_list.parse(in_customerIdList); 
    open res for 
     select * 
     from customer c, 
       in_list v 
     where c.customer_id=v.token; 
    return res; 
end; 

Затем вы можете передать произвольное количество разделенных запятыми идентификаторов клиента в параметре, а также:

  • не получат задержку синтаксического анализа, как SQL для выбора является стабильной
  • SQL, использует простое соединение, а не оператор IN, что довольно быстро
  • В конце концов, это хорошее эмпирическое правило , а не, попадающее в базу данных с любым простым выбором или DML, поскольку это Oracle, который предлагает светлые годы больше, чем MySQL или аналогичные простые базы данных. PL/SQL позволяет скрыть модель хранилища от вашей модели домена приложения эффективным способом.

Хитрость здесь:

  • нам нужен вызов, который принимает длинную строку и хранить где-нибудь, где дб сеанс может получить доступ к нему (например, простой переменной пакета, или dbms_session.set_context)
  • тогда нам нужно представление, которое может разобрать это на строки
  • , а затем у вас есть представление, которое содержит идентификаторы, которые вы запрашиваете, поэтому вам нужно простое соединение с запрошенной таблицей.

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

create or replace view in_list 
as 
select 
    trim(substr (txt, 
      instr (txt, ',', 1, level ) + 1, 
      instr (txt, ',', 1, level+1) 
      - instr (txt, ',', 1, level) -1)) as token 
    from (select ','||aux_in_list.getpayload||',' txt from dual) 
connect by level <= length(aux_in_list.getpayload)-length(replace(aux_in_list.getpayload,',',''))+1 

где aux_in_list.getpayload относится к исходной строке ввода.

Смежные вопросы