Вопрос по – Самый быстрый запрос для проверки существования строки в Oracle?
Я использую Oracle, и у меня очень большая таблица. Мне нужно проверить наличие строки, отвечающей некоторым простым критериям. Как лучше всего это сделать, используя простой SQL?
Вот моё лучшее предположение, и, хотя это может оказаться достаточно быстрым для моих целей, я бы хотел изучить канонический способ в основном сделать SQL Server «существующим». в Oracle:
select count(x_id) from x where x.col_a = value_a and x.col_b = value_b;
Затем count () будет возвращен как логическое значение на другом уровне. Суть в том, что я хочу, чтобы Oracle выполнил минимальный минимум для этого запроса - мне нужно только знать, есть ли строки, соответствующие критериям.
И да, эти столбцы будут определенно проиндексированы.
Я думаю, что использование 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;
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;
Использование 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 строка).