关于索引的使用问题

wg961423 2009-07-01 08:28:34
TABLE表上有唯一索引(UUU,VVV,WWW,XXX,YYY,ZZZ)

在存储过程中:
IF NOT EXISTS(SELECT 0 FROM TABLE WHERE UUU=@UUU AND ISNULL(VVV,'')=ISNULL(@VVV,'') AND ISNULL(WWW,'')=ISNULL(@WWW,'') AND ISNULL(XXX,'')=ISNULL(@XXX,'') AND ISNULL(YYY,0)=ISNULL(@YYY,0) AND ISNULL(ZZZ,0)=ISNULL(@ZZZ,0))
INSERT INTO TABLE (UUU,VVV,WWW,XXX,YYY,ZZZ) VALUES(@UUU,@VVV,@WWW,@XXX,@YYY,@ZZZ)
ELSE
UPDATE TABLE SET AAA=@AAA WHERE UUU=@UUU AND ISNULL(VVV,'')=ISNULL(@VVV,'') AND ISNULL(WWW,'')=ISNULL(@WWW,'') AND ISNULL(XXX,'')=ISNULL(@XXX,'') AND ISNULL(YYY,0)=ISNULL(@YYY,0) AND ISNULL(ZZZ,0)=ISNULL(@ZZZ,0))


这样子能不能用到这个唯一索引呢?如果不能,应该怎么做才能提高速度?
...全文
79 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
ai_li7758521 2009-07-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 haiwer 的回复:]
问题在isnull
[/Quote]海爷正解
wang1231 2009-07-01
  • 打赏
  • 举报
回复
学习中。。。
wg961423 2009-07-01
  • 打赏
  • 举报
回复
看了执行计划,AND ISNULL(XXX,'')=ISNULL(@XXX,'') 这种的,也可以用到索引,成本为65%,如果把字符串的默认值改为''(也就是字符串字段没有NULL的情况了,数字的还有NULL),用 AND XXX=ISNULL(@XXX,'') AND ISNULL(YYY,0)=ISNULL(@YYY,0) ,索引的成本是99%

各位看看还有什么方法?是不是直接Update,再看@@ROWCOUNT 再Insert 这种快呢?
futurecn 2009-07-01
  • 打赏
  • 举报
回复
up 好东西,顶一下!
wg961423 2009-07-01
  • 打赏
  • 举报
回复
错了,AND (VVV=ISNULL(@VVV,'') OR (VVV IS NULL AND ISNULL(@VVV,'') = '')) 有问题,数据少了,应该插入的,但没有插入,被Update了。
wg961423 2009-07-01
  • 打赏
  • 举报
回复


经过测试,
ISNULL(YYY,0)=ISNULL(@YYY,0)

AND (VVV=ISNULL(@VVV,'') OR (VVV IS NULL AND ISNULL(@VVV,'') = ''))
效果一样,应该都没有用到索引。
wg961423 2009-07-01
  • 打赏
  • 举报
回复

AND (VVV=ISNULL(@VVV,'') OR (VVV IS NULL AND ISNULL(@VVV,'') = ''))

是不是这种?
tim_spac 2009-07-01
  • 打赏
  • 举报
回复
AND ISNULL(YYY,0)=ISNULL(@YYY,0)

==>

AND ( (YYY IS NULL and ISNULL(NULLIF(@YYY,0),0)=0) or
(YYY = ISNULL(NULLIF(@YYY,0),0)) )

因为有or逻辑,恐怕还是用不上Index
wg961423 2009-07-01
  • 打赏
  • 举报
回复
程序中字符串NULL和''等同,这个没有问题,但数字(int numeric float)的放''就会变成0,在业务上,0和NULL可不一样啊!总不能把数字的也改成字符串吧!
Yang_ 2009-07-01
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 wg961423 的回复:]
表中除了UUU肯定不为空外,其他的都有可能为空(NULL或''),且由于SQLServer中NULL和''不同,而在我的业务中NULL和''都是做为空处理的,这样写会不会有问题?
[/Quote]
那也不能用ISNULL

ISNULL(VVV,'')=ISNULL(@VVV,'')
改成
VVV=ISNULL(@VVV,'')
OR VVV IS NULL AND ISNULL(@VVV,'') = ''

tim_spac 2009-07-01
  • 打赏
  • 举报
回复
9L的说法是基于NULL值与某个具体值等价的假设,若NULL值存在特别的业务含义则另当别论。
wg961423 2009-07-01
  • 打赏
  • 举报
回复
字符串的可以,那数字的怎么办,可不能把默认值置0啊!
tim_spac 2009-07-01
  • 打赏
  • 举报
回复
NULL 不太好。如果“业务中NULL和''都是做为空处理的”
建议 1. 设置Default: ''
2. 将库中现有的NULL数据更新为''
3. 建一个Trigger, 将被赋值为NULL的数据以''替代

调整后>
1.可简化查询代码; 2.可用上Index
wg961423 2009-07-01
  • 打赏
  • 举报
回复
表中除了UUU肯定不为空外,其他的都有可能为空(NULL或''),且由于SQLServer中NULL和''不同,而在我的业务中NULL和''都是做为空处理的,这样写会不会有问题?
liangCK 2009-07-01
  • 打赏
  • 举报
回复
向学海学习.
昵称被占用了 2009-07-01
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wg961423 的回复:]
有个问题,Update的时候就能用到索引了吗?
[/Quote]


ISNULL相当于函数,会影响索引的选择,没必要的时候不要在字段上加
昵称被占用了 2009-07-01
  • 打赏
  • 举报
回复
IF NOT EXISTS(SELECT 0 FROM TABLE WHERE UUU=@UUU AND VVV=ISNULL(@VVV,'') AND WWW=ISNULL(@WWW,'') AND XXX=ISNULL(@XXX,'') AND YYY=ISNULL(@YYY,0) AND ZZZ=ISNULL(@ZZZ,0)) 
INSERT INTO TABLE (UUU,VVV,WWW,XXX,YYY,ZZZ) VALUES(@UUU,@VVV,@WWW,@XXX,@YYY,@ZZZ)
ELSE
UPDATE TABLE SET AAA=@AAA WHERE UUU=@UUU AND VVV=ISNULL(@VVV,'') AND WWW=ISNULL(@WWW,'') AND XXX=ISNULL(@XXX,'') AND YYY=ISNULL(@YYY,0) AND ZZZ=ISNULL(@ZZZ,0)
昵称被占用了 2009-07-01
  • 打赏
  • 举报
回复
问题在isnull
wg961423 2009-07-01
  • 打赏
  • 举报
回复
有个问题,Update的时候就能用到索引了吗?
liangCK 2009-07-01
  • 打赏
  • 举报
回复
先UPDATE..
然后判断
IF @@ROWCOUNT = 0
--再INSERT
加载更多回复(2)

22,207

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧