关于SELECT 1的效率问题,不要不看查询计划
刚看到一个讨论SELECT 1,SELECT ID,SELECT *的效率问题的推荐贴,里面竟然没有一个人去看查询计划,还有人以测试结果为准。这里普及一下这个问题的知识点。
会用到SELECT 1的地方只有EXISTS和NOT EXISTS,这两个关键字用到的迭代器是三个LOOP,关联方式为SEMI JOIN也就是半连接,所以无论你在EXISTS里的SELECT后面写什么都不会真正去表里查询,最终输出的只有需要比较的条件。
我简单写三个语句,在master库里执行
select *
from spt_values t1
where exists(
select 1 FROM spt_values T2
WHERE T2.number>T1.number
)
select *
from spt_values t1
where exists(
select t2.low,t2.high FROM spt_values T2
WHERE T2.number>T1.number
)
select *
from spt_values t1
where exists(
select * FROM spt_values T2
WHERE T2.number>T1.number
)
执行计划的图片懒得上传了,大家自己去按CTRL+L执行一下,生成的计划是一模一样的。在下方的index seek里,最终输出的都只有number一列,所以这三种写法在比较条件相同的时候是完全一样的,写1不会生成一列计算列,也不会因为SELECT索引键列走某个索引,也不会因为写*去找系统表读所有列。
所以无论实测结果是什么,本质上测试的都是同一个执行计划,所以效率完全没有差异,我爱用SELECT 1只是因为恶趣味,你也可以写SELECT 'SB'来展示你的恶趣味,对效率完全没影响。当别人很诧异的看你的语句时,你就可以低调而又坚定的告诉他:这里是随便写的,不用管它。如果他质疑你,就拿这篇文章扔他脸。