Вопрос по – Самый быстрый запрос для проверки существования строки в Oracle?

11

Я использую 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 выполнил минимальный минимум для этого запроса - мне нужно только знать, есть ли строки, соответствующие критериям.

И да, эти столбцы будут определенно проиндексированы.

Ваш Ответ

4   ответа
1
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;
7

Я думаю, что использование 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;
5
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;
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
16

Использование 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 строка).

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded), or is the sql interpreter smart enough to see that it doesn't really need to expand "Error: User Rate Limit Exceeded Josh Kodroff

Похожие вопросы