Как следует из названия ... Я пытаюсь найти самый быстрый способ с наименьшими накладными расходами, чтобы определить, существует ли запись в таблице или нет.
Пример запроса:
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 через предоставленный M $ драйвер JDBC)
источник
if exists(select null from products where id = @id)
; если в запросе, вызванном непосредственно клиентомselect case when exists (...) then 1 else 0 end
.Ответы:
SELECT TOP 1 products.id FROM products WHERE products.id = ?;
превзойдет все ваши предложения, так как прекратит выполнение после того, как найдет первую запись.источник
id
не является PK. Так что +1 к вашему совету.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
источник
Exists
работаетselect
таким образом, что закрывается, как только будет найдена одна строка. Кроме того, существует просто отмечает наличие записи, а не фактических значений в записи, избавляя от необходимости загружать строку с диска (конечно, при условии, что критерии поиска индексируются). Что касается накладных расходовif
- вам все равно придется потратить это ничтожное время.select top
илиexists
; если их нет, sql Engine должен будет выполнить сканирование таблицы. Это наименее желательный вариант поиска по таблице. Если у вас нет полномочий на создание индексов, вам придется связаться с техническим персоналом на другой стороне, чтобы узнать, корректируют ли они их автоматически или ожидают, что вы предложите индексы.SELECT CASE WHEN EXISTS(..) THEN 1 ELSE 0 END;
Ничто не может победить -
SELECT TOP 1 1 FROM products WHERE id = 'some value';
Вам не нужно считать, чтобы узнать, есть ли данные в таблице. И не используйте псевдоним, если он не нужен.
источник
id
это не первичный ключ. Таким образом, даже если вы не считая вам все еще нужно , чтобы найти все записи , соответствующие, возможно , тысячи из них. По поводу алиасинга - код постоянно дорабатывается. Никогда не знаешь, когда тебе придется вернуться. Псевдонимы помогают предотвратить глупые ошибки времени выполнения; например, уникальное имя столбца, которому не нужен псевдоним, больше не является уникальным, поскольку кто-то создал столбец с таким же именем в другой объединенной таблице.aliasing
. Правильный термин естьqualifying
. Вот более подробное объяснение Алекса Кузнецова . О запросах одной таблицы - теперь это одна таблица . Но позже, когда обнаруживается ошибка, и вы пытаетесь сдержать флуд, клиент нервничает, вы присоединяетесь к другому столу, чтобы увидеть сообщение об ошибке - легко исправляемое сообщение, но не в этот потный момент, наносится небольшой штрих - и вы исправляете ошибка при запоминании никогда не покидать колонну ...SELECT CASE WHEN EXISTS (SELECT TOP 1 * FROM dbo.[YourTable] WHERE [YourColumn] = [YourValue]) THEN CAST (1 AS BIT) ELSE CAST (0 AS BIT) END
Этот подход возвращает вам логическое значение.
источник
Вы также можете использовать
If EXISTS (SELECT 1 FROM dbo.T1 WHERE T1.Name='Scot') BEGIN --<Do something> END ELSE BEGIN --<Do something> END
источник
Не думайте, что кто-то еще упомянул об этом, но если вы уверены, что данные под вами не изменятся, вы можете также применить подсказку 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
источник
SELECT COUNT(*) FROM products WHERE products.id = ?;
Это решение кросс-реляционной базы данных, которое работает во всех базах данных.
источник
Ниже приведен самый простой и быстрый способ определить, существует ли запись в базе данных или нет. Хорошо, что она работает во всех реляционных БД.
SELECT distinct 1 products.id FROM products WHERE products.id = ?;
источник
Для тех, кто наткнулся на это из опыта MySQL или Oracle - MySQL поддерживает предложение LIMIT для выбора ограниченного количества записей, в то время как Oracle использует ROWNUM.
источник
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;
источник
Я использовал это в прошлом, и это не требует полного сканирования таблицы, чтобы увидеть, существует ли что-то. Это супер быстро ...
UPDATE TableName SET column=value WHERE column=value IF @@ROWCOUNT=0 BEGIN --Do work END
источник