我有一个包含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'
(更新用户的所有记录的开销)
答案 0 :(得分:5)
99%的确定性我可以说第一个查询会更高效。
您的群集密钥可能是user_id,因此您的UPDATE语句将非常快速地找到要更新的行。更新在SQL Server中以逻辑方式实现为删除,然后是插入,因此它可能是一个相当昂贵的操作(相对于简单的查找)。
认为UPDATE需要对记录进行独占锁定,并且所有符号都指向语句1。
答案 1 :(得分:1)
为什么不亲自尝试一下。在SQL Management Studio中,依次运行两个查询并启用“包含实际执行计划”。较高的百分比是较慢的查询。
答案 2 :(得分:1)
这里没有明确的答案。如果大多数记录的默认值='N',则在第一种情况下效率最佳。在第二种情况下,最好在大多数情况下默认='Y'。
因此,如果您的大多数用户只有1个电子邮件地址,请使用第二个查询。如果大多数用户至少有2个,请使用第一个。
答案 3 :(得分:1)
在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'检查的开销”非常微不足道,因为您无论如何都需要访问该列来更新它。
答案 4 :(得分:0)
查询的速度取决于几个因素,例如表中的行数,索引,检查约束以及外键和主键。
确定至少在SQL Server中哪个更快的最佳方法是在运行查询时使用包含客户端统计信息和执行计划。比较每个的时间并选择最佳。