Самый быстрый запрос для проверки наличия строки в Oracle?
Я использую Oracle, и у меня очень большая таблица. Мне нужно проверить наличие любой строки, удовлетворяющей некоторым простым критериям. Какой лучший способ сделать это с помощью простого SQL?
Вот мое лучшее предположение, и хотя оно может оказаться достаточно быстрым для моих целей, мне бы хотелось изучить канонический способ, в основном, чтобы SQL Server существовал в Oracle:
select count(x_id) from x where x.col_a = value_a and x.col_b = value_b;
Затем счетчик() будет возвращен как булев в другом уровне. Главное, что я хочу, чтобы Oracle выполнял минимальный минимум для этого запроса - мне нужно знать только, есть ли какие-либо строки, соответствующие критериям.
И да, эти столбцы будут определенно индексироваться.
Ответы
Ответ 1
Использование COUNT (*) в порядке, если вы также используете rownum = 1:
declare
l_cnt integer;
begin
select count(*)
into l_cnt
from x
where x.col_a = value_a
and x.col_b = value_b
and rownum = 1;
end;
Это всегда будет возвращать строку, поэтому нет необходимости обрабатывать исключение NO_DATA_FOUND. Значение l_cnt будет равно 0 (без строк) или 1 (существует не менее 1 строки).
Ответ 2
Я думаю, что использование EXISTS дает более естественный ответ на вопрос, чем попытка оптимизировать запрос COUNT с использованием ROWNUM.
Пусть Oracle сделает для вас оптимизацию ROWNUM.
create or replace function is_exists (
p_value_a varchar2,
p_value_b varchar2)
return boolean
is
v_exists varchar2(1 char);
begin
begin
select 'Y' into v_exists from dual
where exists
(select 1 from x where x.col_a = p_value_a and x.col_b = p_value_a);
exception
when no_data_found then
v_exists := null;
end;
return v_exists is not null;
end is_exists;
Ответ 3
SELECT NULL
FROM x
WHERE x.col_a = value_a
AND x.col_b = value_b
AND rownum = 1
COUNT(*)
, конечно, не самый лучший способ, так как ему нужно будет подсчитывать все строки, а ROWNUM = 1
возвращает, как только найдет первую соответствующую строку.
Здесь код PL/SQL
:
DECLARE
ex INT;
BEGIN
BEGIN
SELECT NULL
INTO ex
FROM dual
WHERE 1 = 1
AND rownum = 1;
DBMS_OUTPUT.put_line('found');
EXCEPTION
WHEN no_data_found THEN
DBMS_OUTPUT.put_line('not found');
END;
END;
Ответ 4
begin
select 'row DOES exist'
into ls_result
from dual
where exists (select null from x where x.col_a = value_a and x.col_b = value_b);
exception
when no_data_found then
ls_result := ' row does NOT exist';
end;