Более эффективный из двух запросов? - PullRequest
3 голосов
/ 14 мая 2009

У меня есть таблица со столбцами user_id, email, default. По умолчанию хранится «Y» или «N» в зависимости от того, является ли электронная почта электронной почтой пользователя по умолчанию. Каждый пользователь может иметь только один адрес электронной почты по умолчанию.

Когда пользователь выполняет обновление или вставку в таблицу, в моем SP я проверяю, передал ли пользователь isDefault как 'Y'. Если это так, мне нужно обновить все записи для этого пользователя, чтобы сделать значение по умолчанию «N». Мой вопрос: учитывая, что нет проблем с блокировкой (не более одного потока будет запрашивать данные из таблицы для конкретного пользователя), который из следующих запросов занимает меньше всего времени:

update table
set default = 'N'
where user_id = 'abc'
and default = 'Y'

(накладные расходы на проверку по умолчанию = 'Y')

OR

update table
set default = 'N'
where user_id = 'abc'

(накладные расходы на обновление всех записей для пользователя)

Ответы [ 5 ]

5 голосов
/ 14 мая 2009

С уверенностью 99% могу сказать, что первый запрос будет более производительным.

Скорее всего, ваш ключ кластеризации - user_id, поэтому ваш оператор UPDATE найдет строку, которая будет обновлена ​​очень быстро. Обновление логически реализовано в SQL Server как удаление, а затем вставка, поэтому это может быть довольно дорогой операцией (по сравнению с простым поиском).

Соедините это с тем фактом, что для ОБНОВЛЕНИЯ требуется эксклюзивная блокировка записи, а все признаки указывают на утверждение 1.

1 голос
/ 14 мая 2009

На фронте Oracle я бы выбрал вариант 1. Сортировка.

У меня будет уникальный индекс, обеспечивающий наличие только одной записи по умолчанию для каждого пользователя, тогда я буду использовать функцию в этом индексе как часть обновления. Вы обновляете только те строки, которые нужно обновить. Кроме того, уникальный индекс минимизирует работу, необходимую для получения электронной почты по умолчанию для данного пользователя, не только для обновления, но и везде, где вы используете эту функцию для получения строки.

drop table user_email;

create table user_email 
(userid varchar2(4) not null, default_ind varchar2(1) not null, 
email varchar2(30));

create unique index ue_x on user_email 
  (userid, decode(default_ind,'Y','Y',email));

insert into user_email (userid, default_ind, email) values ('fred','N','a');
insert into user_email (userid, default_ind, email) values ('fred','N','b');
insert into user_email (userid, default_ind, email) values ('fred','Y','c');

update user_email
set default_ind = 'N'
where userid = 'fred'
and decode(default_ind,'Y','Y',email) = 'Y';

update user_email
set default_ind = 'Y'
where userid = 'fred'
and email = 'a';

PS. «Накладные расходы на проверку по умолчанию = 'Y'» довольно незначительны, так как вам все равно необходим доступ к этому столбцу для его обновления.

1 голос
/ 14 мая 2009

Почему бы не попробовать их самостоятельно. В SQL Management Studio запустите оба запроса один за другим и включите «Включить фактический план выполнения». Какой процент выше, тем медленнее запрос.

1 голос
/ 14 мая 2009

Здесь нет однозначного ответа. Ваша эффективность будет наилучшей в первом случае, если по умолчанию = 'N' для большинства записей. Во втором случае в большинстве случаев будет лучше, если default = 'Y'.

Так что, если у большинства ваших пользователей только один адрес электронной почты, используйте второй запрос. Если у большинства пользователей есть хотя бы 2, используйте первый.

0 голосов
/ 14 мая 2009

Скорость запросов зависит от нескольких факторов, таких как количество строк в таблице, индексы, контрольные ограничения и внешние и первичные ключи.

Лучший способ определить, что быстрее, по крайней мере в SQL Server, - это использовать статистику клиента include и план выполнения при запуске запроса. Сравните время для каждого и выберите лучшее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...