求高手解惑,语句性能比较
在做项目时,碰到一个句子,感觉有点意思,但具体性能比较,哪个好就不知道了,求高手解惑。贴码:
- 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其实也会做表扫描,它是算为“不可参数化”的样式。
[解决办法]
[解决办法]
做一个测试来说明这个观点
- 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
[解决办法]
[解决办法]
[解决办法]