读书人

求高手解惑语句性能比较解决方法

发布时间: 2013-01-25 15:55:30 作者: rapoo

求高手解惑,语句性能比较
在做项目时,碰到一个句子,感觉有点意思,但具体性能比较,哪个好就不知道了,求高手解惑。贴码:


[解决办法]
做一个测试来说明这个观点

--用于生成示例数据,这里是100W条数据
if OBJECT_ID('Test') is not null drop table Test
create table Test(ID [bigint] identity primary key,
ColumnA char(1) NULL,
ColumnB char(1) NULL)
INSERT INTO dbo.Test SELECT case
when abs(checksum(newid()))%(3) = 0 then char(65+abs(checksum(newid()))%(26))
when abs(checksum(newid()))%(2) = 0 then char(97+abs(checksum(newid()))%(26)) end, case
when abs(checksum(newid()))%(3) = 0 then char(65+abs(checksum(newid()))%(26))
when abs(checksum(newid()))%(2) = 0 then char(97+abs(checksum(newid()))%(26)) end

DECLARE @i AS INT, @rc AS INT,@max int;
SET @rc = 1;
SET @max = 1000000;
set @i = ceiling(log10(@max)/LOG10(2))-1;
WHILE @rc <= @i
BEGIN
INSERT INTO dbo.Test SELECT case


when abs(checksum(newid()))%(3) = 0 then char(65+abs(checksum(newid()))%(26))
when abs(checksum(newid()))%(2) = 0 then char(97+abs(checksum(newid()))%(26)) end, case
when abs(checksum(newid()))%(3) = 0 then char(65+abs(checksum(newid()))%(26))
when abs(checksum(newid()))%(2) = 0 then char(97+abs(checksum(newid()))%(26)) end
FROM dbo.Test;
SET @rc = @rc +1 ;
END
select @max = @max - @@IDENTITY
INSERT INTO dbo.Test
SELECT top(@max) case
when abs(checksum(newid()))%(3) = 0 then char(65+abs(checksum(newid()))%(26))
when abs(checksum(newid()))%(2) = 0 then char(97+abs(checksum(newid()))%(26)) end, case
when abs(checksum(newid()))%(3) = 0 then char(65+abs(checksum(newid()))%(26))
when abs(checksum(newid()))%(2) = 0 then char(97+abs(checksum(newid()))%(26)) end FROM dbo.Test


--方案一
SELECT * FROM TEST
WHERE ID NOT IN
(
SELECT ID FROM TEST
WHERE ColumnA='A' AND ColumnB='B'
)
--直接执行会提示缺少索引
/*
USE [mydb]
GO
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[Test] ([ColumnA],[ColumnB])
INCLUDE ([ID])
GO
*/
--得到计划1

[img=http://my.csdn.net/my/album/detail/1337909][/img]

--按提示创建该索引,再次执行
--方案二
SELECT * FROM TEST
WHERE ID NOT IN
(
SELECT ID FROM TEST
WHERE ColumnA='A' AND ColumnB='B'
)
--得到计划2

[img=http://my.csdn.net/my/album/detail/1337910][/img]
--方案三
SELECT * FROM TEST
WHERE NOT (ColumnA='A' AND ColumnB='B')
--得到计划3

[img=http://my.csdn.net/my/album/detail/1337911][/img]

--方案四
SELECT * FROM TEST
WHERE ((ColumnA='A' AND ColumnB<>'B')
OR (ColumnA<>'A' AND ColumnB<>'B')
OR (ColumnA<>'A' AND ColumnB='B')
)
--得到计划4

[img=http://my.csdn.net/my/album/detail/1337912][/img]
--方案五
SELECT * FROM TEST a
WHERE NOT exists
(
SELECT ID FROM TEST b
WHERE ColumnA='A' AND ColumnB='B' and a.ID = b.id
)
--得到计划5

[img=http://my.csdn.net/my/album/detail/1337913][/img]
--方案六
select * from TEST
except
select * from TEST WHERE ColumnA='A' AND ColumnB='B'
--得到计划6

[img=http://my.csdn.net/my/album/detail/1337927][/img]
[解决办法]
引用:
引用:
做一个测试来说明这个观点

SQL code


你的数据是随机分布的。这可能不符合楼主的实际情况。
索引肯定是必须的。但索引有没有效就不一定了。

楼主搞的逻辑第一个简单点外。其他的逻辑搞的有点复杂了

楼主的条件是
WHERE ColumnA='A' AND ColumnB='B'
我认为这个条件的选择性是非常高的,那么 not in 的查询选择性就非常低,跟数据是否随机分布没有关系
[解决办法]
引用:

引用:
引用:
做一个测试来说明这个观点

SQL code


你的数据是随机分布的。这可能不符合楼主的实际情况。
索引肯定是必须的。但索引有没有效就不一定了。

楼主搞的逻辑第一个

简单点外。其他的逻辑搞的有点复杂了
楼主的条件是
WHERE ColumnA='A' AND ColumnB='B'
我认为这个条件的选择性是非常高的,那……

按照通常的想 应该选择性应该非常高了.但主要还是以实际的情况为准.
可能分布不OK的话.选择性也不一定高.
[解决办法]
引用:
实际应用中,数据也就几千条而已,一年增加也就一千条左右,但没加索引,我在写的时候是用的贴中的第3种方案,筛选条件只是如果ColumnA为A时,ColumnB不能为B(ColumnB为B时,ColumnA必然为A),并且不能直接判断ColumnB!='B'.

索引是提升查找速度的有效方法.这个不能少.但是有索引不一定能提升速度.

读书人网 >SQL Server

热点推荐