Самый быстрый запрос для проверки наличия строки в 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;