Самый быстрый способ определить, существует ли запись

Как видно из названия... Я пытаюсь выяснить самый быстрый способ с наименьшими издержками, чтобы определить, существует ли запись в таблице или нет.

Пример запроса:

SELECT COUNT(*) FROM products WHERE products.id = ?;

    vs

SELECT COUNT(products.id) FROM products WHERE products.id = ?;

    vs

SELECT products.id FROM products WHERE products.id = ?;

Скажите, что ? обменивается с помощью 'TB100'... как первый, так и второй запросы вернут тот же результат (скажем... 1 для этой беседы). Последний запрос вернет 'TB100', как ожидалось, или ничего, если id отсутствует в таблице.

Цель состоит в том, чтобы выяснить, находится ли id в таблице или нет. Если нет, программа будет вставлять запись, если она есть, программа пропустит ее или выполнит запрос UPDATE, основанный на другой программной логике, вне сферы действия этого вопроса.

Что быстрее и имеет меньше накладных расходов? (Это будет повторяться десятки тысяч раз за прогон программы и будет выполняться много раз в день).

(Запуск этого запроса с M $SQL Server с Java через MD-драйвер JDBC)

Ответ 1

SELECT TOP 1 products.id FROM products WHERE products.id = ?; будет превосходить все ваши предложения, поскольку он прекратит выполнение после того, как он найдет первую запись.

Ответ 2

EXISTS (или NOT EXISTS) специально разработан для проверки того, существует ли что-то и, следовательно, должен быть (и является) лучшим вариантом. Он будет останавливаться на первой строке, которая соответствует, поэтому для нее не требуется предложение TOP, и на самом деле он не выбирает никаких данных, поэтому накладные расходы по размеру столбцов отсутствуют. Вы можете безопасно использовать SELECT * здесь - не что иное, как SELECT 1, SELECT NULL или SELECT AnyColumn... (вы даже можете использовать недопустимое выражение типа SELECT 1/0 и он не сломается).

IF EXISTS (SELECT * FROM Products WHERE id = ?)
BEGIN
--do what you need if exists
END
ELSE
BEGIN
--do what needs to be done if not
END

Ответ 3

Ничего не может побить -

SELECT TOP 1 1 FROM products WHERE id = 'some value';

Вам не нужно подсчитывать, есть ли данные в таблице. И не используйте псевдоним, когда это не необходимо.

Ответ 4

SELECT CASE WHEN EXISTS (SELECT TOP 1 *
                         FROM dbo.[YourTable] 
                         WHERE [YourColumn] = [YourValue]) 
            THEN CAST (1 AS BIT) 
            ELSE CAST (0 AS BIT) END

Этот подход возвращает логическое значение для вас.

Ответ 5

Вы также можете использовать

 If EXISTS (SELECT 1 FROM dbo.T1 WHERE T1.Name='Scot')
    BEGIN
         --<Do something>
    END 

ELSE    
     BEGIN
       --<Do something>
     END

Ответ 6

SELECT COUNT(*) FROM products WHERE products.id = ?;

Это решение для перекрестной реляционной базы данных, которое работает во всех базах данных.

Ответ 7

Не думайте, что кто-то упомянул об этом, но если вы уверены, что данные не будут меняться под вами, вы можете также применить подсказку NoLock, чтобы убедиться, что она не заблокирована при чтении.

SELECT CASE WHEN EXISTS (SELECT 1 
                     FROM dbo.[YourTable] WITH (NOLOCK)
                     WHERE [YourColumn] = [YourValue]) 
        THEN CAST (1 AS BIT) 
        ELSE CAST (0 AS BIT) END

Ответ 8

create or replace procedure ex(j in number) as
i number;
begin
select id into i from student where id=j;
if i is not null then
dbms_output.put_line('exists');
end if;
exception
   when no_data_found then
        dbms_output.put_line(i||' does not exists');

end;

Ответ 9

Я использовал это в прошлом, и он не требует полного сканирования таблицы, чтобы увидеть, существует ли что-то. Это супер быстро...

UPDATE TableName SET column=value WHERE column=value
IF @@ROWCOUNT=0
BEGIN
     --Do work
END             

Ответ 10

Ниже приведен самый простой и быстрый способ определить, существует ли запись в базе данных или нет. Хорошо, что это работает во всех Relational DB's

SELECT distinct 1 products.id FROM products WHERE products.id = ?;

Ответ 11

   DECLARE @USER TABLE(SM_Tbl_Name nvarchar(100),SM_Col_Namenvarchar(100),SM_Disp_Name nvarchar(200),SM_Data_Type  nvarchar(100),SM_Is_Required BIT,
   SM_UI_Tag nvarchar(100),SM_Master_Table nvarchar(100),SM_Text_Field,nvarchar(100),SM_Value_Field,nvarchar(100),SM_Where_Cond nvarchar(400),SM_Is_Readonly BIT,SM_Isactive BIT,SM_Status VARCHAR(1))


  INSERT INTO @USER(SM_Tbl_Name,SM_Col_Name,SM_Disp_Name,SM_Data_Type,SM_Is_Required,SM_UI_Tag,SM_Master_Table,SM_Text_Field,SM_Value_Field,SM_Where_Cond,SM_Is_Readonly,SM_Isactive,SM_Status)

  SELECT 'SADM_Users' as SM_Tbl_Name,'Flex_3'as SM_Col_Name,'Salesman Status Principal' as SM_Disp_Name,'Int' as SM_Data_Type,'0' as SM_Is_Required,'DropDown' as SM_UI_Tag,'ADM_LOVs' as SM_Master_Table,'ALOV_Name' as SM_Text_Field,'ALOV_Id' as SM_Value_Field, 'ALOV_Type=''SALESMAN_STATUS_PRINCIPAL''' as SM_Where_Cond,'0' as SM_Is_Readonly,'1' as SM_Isactive,'I' as SM_Status
  UNION
  SELECT 'SADM_Users' as SM_Tbl_Name,'Flex_4'as SM_Col_Name,'Salesman Status Channel' as SM_Disp_Name,'Int' as SM_Data_Type,'0' as SM_Is_Required,'DropDown' as SM_UI_Tag,'ADM_LOVs' as SM_Master_Table,'ALOV_Name' as SM_Text_Field,'ALOV_Id' as SM_Value_Field, 'ALOV_Type=''SALESMAN_STATUS_CHANNEL''' as SM_Where_Cond,'0' as SM_Is_Readonly,'1' as SM_Isactive,'I' as SM_Status
  UNION
  SELECT 'SADM_Users' as SM_Tbl_Name,'Flex_5'as SM_Col_Name,'Supervisor Status Principal' as SM_Disp_Name,'Int' as SM_Data_Type,'0' as SM_Is_Required,'DropDown' as SM_UI_Tag,'ADM_LOVs' as SM_Master_Table,'ALOV_Name' as SM_Text_Field,'ALOV_Id' as SM_Value_Field, 'ALOV_Type=''SUPERVISOR_STATUS_PRINCIPAL''' as SM_Where_Cond,'0' as SM_Is_Readonly,'1' as SM_Isactive,'I' as SM_Status
  UNION 
  SELECT 'SADM_Users' as SM_Tbl_Name,'Flex_6'as SM_Col_Name,'Supervisor Status Channel' as SM_Disp_Name,'Int' as SM_Data_Type,'0' as SM_Is_Required,'DropDown' as SM_UI_Tag,'ADM_LOVs' as SM_Master_Table,'ALOV_Name' as SM_Text_Field,'ALOV_Id' as SM_Value_Field, 'ALOV_Type=''SUPERVISOR_STATUS_CHANNEL''' as SM_Where_Cond,'0' as SM_Is_Readonly,'1' as SM_Isactive,'I' as SM_Status

 INSERT INTO [dbo].[SADM_Flex_Ext_Def](SM_Tenant_Id,SM_Bu_Id,SM_Tbl_Name,SM_Col_Name,SM_Disp_Name,SM_Data_Type,SM_Is_Required,SM_UI_Tag,SM_Master_Table,SM_Text_Field,SM_Value_Field,SM_Where_Cond,SM_Is_Readonly,SM_Isactive,SM_Status)
 SELECT 1 as  SM_Tenant_Id,1 as SM_Bu_Id,T.SM_Tbl_Name,T.SM_Col_Name,T.SM_Disp_Name,T.SM_Data_Type,T.SM_Is_Required,T.SM_UI_Tag,T.SM_Master_Table,T.SM_Text_Field,T.SM_Value_Field,T.SM_Where_Cond,T.SM_Is_Readonly,T.SM_Isactive,T.SM_Status FROM @USER as T
 left join SADM_Flex_Ext_Def as TT on TT.SM_Tenant_Id=97 and TT.SM_Bu_Id=41 and TT.SM_Col_Name=T.SM_Col_Name and TT.SM_Tbl_Name=T.SM_Tbl_Name
 WHERE TT.SM_Id IS NULL
 PRINT 'SADM_Flex_Ext_Def - Insert: ' + CONVERT(VARCHAR, @@ROWCOUNT)
 GO