首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

求好手解惑,语句性能比较

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

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

SQL code
SELECT  * FROM TESTWHERE 主键 NOT IN(SELECT 主键 FROM TESTWHERE ColumnA='A' AND ColumnB='B')


SQL code
SELECT  * FROM TESTWHERE NOT (ColumnA='A' AND ColumnB='B')


SQL code
SELECT * FROM TESTWHERE ((ColumnA='A' AND ColumnB<>'B')    OR (ColumnA<>'A' AND ColumnB<>'B')    OR (ColumnA<>'A' AND ColumnB='B'))


[解决办法]
SELECT * FROM TEST
WHERE ((ColumnA='A' AND ColumnB<>'B')
OR (ColumnA<>'A' AND ColumnB<>'B')
OR (ColumnA<>'A' AND ColumnB='B')
)

这个理论上会好一点,因为上面两个都会造成表扫描
[解决办法]
SELECT 主键 FROM TEST
WHERE ColumnA='A' AND ColumnB='B'

这个数据量不多的话,比如得到几十个几百个id的话
第一个方案最优

如果会很多那么修改会not exists
SQL code
select * from  TEST as awhere not exists (select 1 from TESTWHERE ColumnA='A' AND ColumnB='B' and 主键=a.主键)
[解决办法]
SQL code
--最好的解决方法declare @StartTime datetimeset @StartTime = getdate()[你的SQL 语句]select datediff(ms,@StartTime,getdate())--时间最小,语句最优
[解决办法]
同意2楼,因为带exit量词的相关子查询只关心内层查询是否有返回值,并不需要查询具体值,因此效率可能会比不相关子查询高
[解决办法]
not exists其实也会做表扫描,它是算为“不可参数化”的样式。
[解决办法]
探讨
not exists其实也会做表扫描,它是算为“不可参数化”的样式。

[解决办法]
做一个测试来说明这个观点
SQL code
--用于生成示例数据,这里是100W条数据if OBJECT_ID('Test') is not null drop table Testcreate 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)) endDECLARE @i AS INT, @rc AS INT,@max int;SET @rc = 1;SET @max = 1000000;set @i = ceiling(log10(@max)/LOG10(2))-1;WHILE @rc  <= @iBEGIN    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 ;ENDselect @max = @max - @@IDENTITYINSERT 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
[解决办法]


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

SQL code


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

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

[解决办法]
探讨
引用:
引用:
做一个测试来说明这个观点

SQL code


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

楼主搞的逻辑第一个

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

[解决办法]
探讨
实际应用中,数据也就几千条而已,一年增加也就一千条左右,但没加索引,我在写的时候是用的贴中的第3种方案,筛选条件只是如果ColumnA为A时,ColumnB不能为B(ColumnB为B时,ColumnA必然为A),并且不能直接判断ColumnB!='B'.

热点排行