sqlserverexistsin
‘壹’ sql server 嵌套查询语句中什么时候用in,什么时候又用exists!
sqlserver嵌套查询语句中使用in或者exists的场景和原则如下:
如果查询的两个表大小相当,那么用in和exists差别不大。两者都可以使用。
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。所以当有多重循环,使用in更合适,效率越高。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in。
NOT EXISTS,exists的用法跟in不一样,一般都需要和子表进行关联,而且关联时,需要用索引,这样就可以加快速度。
‘贰’ SQLSERVER璇鍙 in鍜宔xists鍝涓鏁堢巼楂樻湰浜烘祴璇曡瘉鏄
鐩稿悓搴撶粨鏋勪笅锛屽緢鏄庢樉 Exists鏁堢巼楂
in 鍦ㄥ瓧绗︿覆涓嬬殑鏁堢巼鏄寰堜绠镄勶纴涓昏佸师锲犳槸绱㈠紩
濡傛灉鏄疘NT鍨嬶纴链夌储寮旷殑𨱍呭喌锛屽熀链涓婃病澶澶у尯鍒
娌℃湁澶澶ф暟鎹镄勬儏鍐碉纴锘烘湰涓娄笉鐢ㄧ籂缁撹繖浜涗笢瑗
‘叁’ SQLSERVER语句 in和exists哪个效率高本人测试证明
效率高低通常和需要的条件有关,比如数据量,索引的 创建与否
同等条件下,exists叫存在检测,检测到第一个存在的记录就返回了
in可以理解为在。。。中。通常会进行全表扫描。
exists比in要性能高一些
‘肆’ sql中in和exist语句的区别
两者都能实现表功能查询,主要区别如下:
1、适用表的类型不同。
in是子查询为驱动表,外面的表为被驱动表,故适用于子查询结果集小而外面的表结果集大的情况。
exists是外面的表位驱动表,子查询里面的表为被驱动表,故适用于外面的表结果集小而子查询结果集大的情况。
2、子查询关联不同。
exists一般都是关联子查询。对于关联子查询,必须先执行外层查询,接着对所有通过过滤条件的记录,执行内层查询。外层查询和内层查询相互依赖,因为外层查询会把数据传递给内层查询。
in则一般都是非关联子查询,非关联子查询则必须先完成内层查询之后,外层查询才能介入。
3、执行次数不同。
IN 语句:只执行一次,确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。
EXISTS语句:执行次数根据表的长度而定。指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。
‘伍’ SqlServer中in和exists的区别效率问题
in和exists
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表梁或进行查询。
如果两个表中一个较小,一个是大表悄渣神,则子查询表大的用exists,子查启亏询表小的用in:
例如:表A(小表),表B(大表)1:select * from A where cc in (select cc from B)
效率低,用到了A表上cc列的索引;select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。
相反的2:select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
in 与 =的区别
select name from student where name in ('zhang','wang','li','zhao');与
select name from student where name='zhang' or name='li' or
name='wang' or name='zhao'
的结果是相同的。
‘陆’ SQLSERVER语句 in和exists哪个效率高本人测试证明
例如下面两个SQL语句蠢并
1 SELECT OrderNo, SiteCode, AreaCode
2 FROM SchelingProgram
3 WHERE AreaCode IN ( 'P', 'M' ) AND SiteCode IN ( SELECT SiteCode
4 FROM EnvBasicInfo
5 WHERE cityiD = 31 ) AND OrderNo NOT IN (
6 SELECT OrderNo
7 FROM KK_DeliveryinfoTmp )
上面SQL语句IN里面有IN和NOT IN
1 SELECT OrderNo, SiteCode, AreaCode
2 FROM SchelingProgram
3 WHERE ( AreaCode IN ( 'P', 'M' ) AND SiteCode IN ( SELECT SiteCode
4 FROM EnvBasicInfo
5 WHERE cityiD = 31 )
6 ) AND NOT EXISTS ( SELECT OrderNo
7 FROM KK_DeliveryinfoTmp
8 WHERE KK_DeliveryinfoTmp.OrderNo = SchelingProgram.OrderNo )
上面的SQL语句IN里面又有NOT EXISTS
这样的情况很难测试同等条件下IN语句和EXISTS语句的效率
还有一个非SARG运算符
在《SQLSERVER企业级平台管理实践》的第424页里提到:
SQLSERVER对筛选条件(search argument/SARG)的写法有一定的建议
对于不使用SARG运算符的表达式,索引是没有用的,SQLSERVER对它们很难使用比较优化的做法。非SARG运算符包括
NOT、<>、NOT EXISTS、NOT IN、NOT LIKE和内部函数,例如:Convert、Upper等咐烂
所以当您的表中有索引并且SQL语句包含非SARG运带简迹算符,那么当测试SQL语句的执行时间的时候肯定相差很大,
因为有些SQL语句走索引,有些SQL语句不走索引
建表脚本
注意:两个表中都有索引!!
CT_FuelingData表
1 USE [GPOSDB]
2 GO
3 /****** 对象: Table [dbo].[CT_FuelingData] 脚本日期: 08/24/2013 11:00:34 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8 SET ANSI_PADDING ON
9 GO
10 CREATE TABLE [dbo].[CT_FuelingData](
11 [RecordNO] [int] IDENTITY(1,1) NOT NULL,
12 [I_FD_StationNo] [int] NOT NULL,
13 [VC_FD_No] [varchar](50) NOT NULL,
14 [VC_FD_Cardno] [varchar](50) NOT NULL,
15 [I_FD_CardStatus] [int] NULL,
16 [LI_FD_CTC] [bigint] NOT NULL,
17 [I_FD_TypeCode] [int] NULL,
18 [I_FD_PumpID] [int] NOT NULL,
19 [VC_FD_OilType] [varchar](50) NULL,
20 [DE_FD_Volume] [decimal](18, 2) NULL,
21 [DE_FD_Price] [decimal](18, 2) NULL,
22 [DE_FD_Amount] [decimal](18, 2) NULL,
23 [I_FD_Point] [decimal](10, 2) NULL,
24 [D_FD_DateTime] [datetime] NOT NULL,
25 [VC_FD_GroupNo] [varchar](50) NULL,
26 [D_FD_GroupDate] [datetime] NULL,
27 [DE_FD_CardAmount] [decimal](18, 2) NULL,
28 [DE_FD_VolumeTotals] [decimal](18, 2) NULL,
29 [DE_FD_AmountTotals] [decimal](18, 2) NULL,
30 [I_FD_ISSend] [int] NULL,
31 [VC_FD_CardMoneyauthFile] [varchar](50) NULL,
32 [D_Month] [datetime] NULL,
33 CONSTRAINT [PK_CT_FuelingData_1] PRIMARY KEY CLUSTERED
34 (
35 [VC_FD_No] ASC
36 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
37 ) ON [PRIMARY]
38
39 GO
40 SET ANSI_PADDING OFF
CT_InhouseCard表
1 USE [GPOSDB]
2 GO
3 /****** 对象: Table [dbo].[CT_InhouseCard] 脚本日期: 08/24/2013 10:59:58 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8 SET ANSI_PADDING ON
9 GO
10 CREATE TABLE [dbo].[CT_InhouseCard](
11 [RecordNO] [int] IDENTITY(1,1) NOT NULL,
12 [VC_IC_CardNO] [varchar](50) NOT NULL,
13 [VC_IC_PhysicalNO] [varchar](50) NULL,
14 [I_IC_CardType] [int] NULL,
15 [VC_IC_UserName] [varchar](50) NULL,
16 [VC_IC_JobNO] [varchar](50) NULL,
17 [VC_IC_UserID] [varchar](50) NULL,
18 [VC_IC_Password] [varchar](50) NULL,
19 [DE_IC_CardAmount] [decimal](18, 2) NULL,
20 [DE_IC_AppendAmount] [decimal](18, 2) NULL,
21 [DE_IC_ConsumerAmount] [decimal](18, 2) NULL,
22 [I_IC_ISLost] [int] NULL,
23 [D_IC_UsedDateTime] [datetime] NULL,
24 [D_IC_UselifeDateTime] [datetime] NULL,
25 [I_IC_IssueStationNO] [int] NULL,
26 [VC_IC_IssuerNO] [varchar](50) NULL,
27 [D_IC_IssueDateTime] [datetime] NULL,
28 [D_IC_LastUpdateDateTime] [datetime] NULL,
29 [I_IC_CardStatus] [int] NULL,
30 [VC_IC_Remark] [varchar](256) NULL,
31 CONSTRAINT [PK_CT_InhouseCard] PRIMARY KEY CLUSTERED
32 (
33 [VC_IC_CardNO] ASC
34 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
35 ) ON [PRIMARY]
36
37 GO
38 SET ANSI_PADDING OFF
‘柒’ SQL中IN和EXISTS用法的区别
SQL中IN和EXISTS用法的区别
NOT IN
SELECT DISTINCT MD001 FROM BOMMD WHERE MD001 NOT IN (SELECT MC001 FROM BOMMC)
NOT EXISTS,exists的用法跟in不一样,一般都需要和子表进行关联,而且关联时,需要用索引,这样就可以加快速度
select DISTINCT MD001 from BOMMD WHERE NOT EXISTS (SELECT MC001 FROM BOMMC where BOMMC.MC001 = BOMMD.MD001)
exists是用来判断是否存在的,当exists(查询)中的查询存在结果时则返回真,否则返回假。not exists则相反。
exists做为where 条件时,是先对where 前的主查询询进行查询,然后用主查询的结果一个一个的代入exists的查询进行判断,如果为真则输出当前这一条主查询的结果,否则不输出。
in和exists
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。
如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:表A(小表),表B(大表)1:select * from A where cc in (select cc from B)
效率低,用到了A表上cc列的索引;select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。
相反的2:select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
in 与 =的区别
select name from student where name in ('zhang','wang','li','zhao');
与
select name from student where name='zhang' or name='li' or name='wang' or name='zhao'
的结果是相同的。
‘捌’ hibernate涓镄剆ession.flush鍜宑ommit镄勫尯鍒
1銆乫lush()鏂规硶杩涜屾竻鐞嗙紦瀛樼殑镎崭綔,镓ц屼竴绯诲垪镄凷QL璇鍙,浣嗕笉浼氭彁浜や簨锷;commit()鏂规硶浼氩厛璋幂敤flush()鏂规硶,铹跺悗鎻愪氦浜嫔姟. 鎻愪氦浜嫔姟镒忓懗镌瀵规暟鎹搴撴墍锅氱殑镟存柊浼氭案涔呬缭鎸佷笅𨱒 镓璋撴竻鐞,鏄鎸嘓ibernate 鎸夌収鎸佷箙鍖栬薄镄勭姸镐佹潵钖屾ユ洿鏂版暟鎹搴
2銆丗lush()钖庡彧鏄灏咹ibernate缂揿瓨涓镄勬暟鎹鎻愪氦鍒版暟鎹搴,濡傛灉杩欐椂鏁版嵁搴揿勫湪涓涓浜嬬墿褰扑腑,鍒欐暟鎹搴揿皢杩欎簺SQL璇鍙ョ紦瀛樿捣𨱒,褰揌ibernate杩涜宑ommit镞,浼氩憡璇夋暟鎹搴,浣犲彲浠ョ湡姝f彁浜や简,杩欐椂鏁版嵁镓崭细姘镐箙淇濆瓨涓嬫潵,涔熷氨鏄琚鎸佷箙鍖栦简.
3銆乧ommit阍埚逛簨鐗╃殑锛宖lush阍埚圭紦瀛樼殑锛 鏁版嵁钖屾ュ埌鏁版嵁搴扑腑钖庡彧瑕佹病链塩ommit杩樻槸鍙浠rollback镄勚
鍙浠ヨ繖涔堢悊瑙o纴hibiernate链変簩绾х紦瀛桡纴钥屽钩镞朵竴鑸鍙鐢ㄤ竴绾х紦瀛桡纸榛樿ゅ紑钖锛夛纴涔熷氨鏄痵ession绾х殑缂揿瓨銆傚勪簬涓涓浜嫔姟褰扑腑锛屽綋save镄勬椂鍊欙纴鍙鏄鎶婄浉搴旂殑insert琛屼负锏昏板湪浜嗕互鍙婄紦瀛树笂锛岃宖lush鏄鎶婄紦瀛樻竻绌猴纴钖屾椂鎶奿nsert琛屼负锏昏板湪鏁版嵁搴撶殑浜嫔姟涓娿傚綋commit鎻愪氦涔嫔悗锛屾墠浼氭墽琛岀浉搴旂殑insert浠g爜锛岃宑ommit鍙堟槸闅愭х殑璋幂敤flush镄勶纴闾e湪commit涔嫔墠璋幂敤flush镄勪綔鐢ㄧ殑浠涔堬纻鎴戠殑鐞呜В鏄阒叉㈠氭浔SQL璇鍙ュ啿绐侊纴杩欐槸锲犱负flush鍒版暟鎹搴扑腑镓ц孲QL璇鍙ョ殑椤哄簭涓嶆槸鎸夌収浣犱唬镰佺殑鍏埚悗椤哄簭锛岃屾槸鎸夌収insert锛寀pdate....delete镄勯‘搴忔墽琛岀殑锛屽傛灉浣犱笉鎸夌収杩欎釜椤哄簭鍦ㄤ唬镰佷腑缂栧啓锛屽傛灉阃昏緫涓镞﹀嚭阌椤氨浼氭姏exception浜嗭纴瑙e喅杩欎釜镄勫姙娉曚箣涓灏辨槸鍦ㄥ彲鑳藉叾鍐茬獊镄凷QL镎崭綔钖庨溃flush涓涓嬶纴阒叉㈠悗闱㈢殑璇鍙ュ叾鍐茬獊
钖屾椂flush镄勪綔鐢锛屼篃链夋彁浜ゅぇ閲忔暟鎹镞跺欐竻鐞嗙紦瀛樼殑浣灭敤
鍒嗘瀽涓嬮溃涓娈典唬镰侊细
[java] view plain
public void testSave1() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
User1 user = new User1();
user.setName("𨱒庡洓");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
//锲犱负user镄勪富阌鐢熸垚绛栫暐閲囩敤镄勬槸uuid锛屾墍浠ヨ皟鐢ㄥ畬鎴恠ave钖庯纴鍙鏄灏唘ser绾冲叆鍒颁简session镄勭$悊
//涓崭细鍙戝嚭insert璇鍙ワ纴浣嗘槸id宸茬粡鐢熸垚锛宻ession涓璭xistsInDatebase鐘舵佷负false
session.save(user);
//璋幂敤flush锛宧ibernate浼氭竻鐞嗙紦瀛桡纴镓ц宻ql
//濡傛灉鏁版嵁搴撶殑闅旂荤骇鍒璁剧疆涓烘湭鎻愪氦璇伙纴闾d箞鎴戜滑鍙浠ョ湅鍒癴lush杩囩殑鏁版嵁
//骞朵笖session涓璭xistsInDatebase鐘舵佷负true </span>
session.flush();
//鎻愪氦浜嫔姟
//榛樿ゆ儏鍐典笅commit镎崭綔浼氩厛镓ц宖lush娓呯悊缂揿瓨锛屾墍浠ヤ笉鐢ㄦ樉绀虹殑璋幂敤flush
//commit钖庢暟鎹鏄镞犳硶锲炴粴镄
tx.commit();
}catch(Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testSave2() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
User2 user = new User2();
user.setName("寮犱笁1");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
//锲犱负user镄勪富阌鐢熸垚绛栫暐涓簄ative,镓浠ヨ皟鐢╯ession.save钖庯纴灏嗘墽琛宨nsert璇鍙ワ纴杩斿洖链夋暟鎹搴撶敓鎴愮殑id
//绾冲叆浜唖ession镄勭$悊锛屼慨鏀逛简session涓璭xistsInDatebase鐘舵佷负true
//濡傛灉鏁版嵁搴撶殑闅旂荤骇鍒璁剧疆涓烘湭鎻愪氦璇伙纴闾d箞鎴戜滑鍙浠ョ湅鍒皊ave杩囩殑鏁版嵁
session.save(user);
tx.commit();
}catch(Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
HibernateUtils.closeSession(session);
}
} </span>
[java] view plain
<span style="font-family:Arial;font-size:12px;">public void testSave1() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
User1 user = new User1();
user.setName("𨱒庡洓");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
//锲犱负user镄勪富阌鐢熸垚绛栫暐閲囩敤镄勬槸uuid锛屾墍浠ヨ皟鐢ㄥ畬鎴恠ave钖庯纴鍙鏄灏唘ser绾冲叆鍒颁简session镄勭$悊
//涓崭细鍙戝嚭insert璇鍙ワ纴浣嗘槸id宸茬粡鐢熸垚锛宻ession涓璭xistsInDatebase鐘舵佷负false
session.save(user);
<span style="background-color: rgb(255, 255, 255);"> //璋幂敤flush锛宧ibernate浼氭竻鐞嗙紦瀛桡纴镓ц宻ql
//濡傛灉鏁版嵁搴撶殑闅旂荤骇鍒璁剧疆涓烘湭鎻愪氦璇伙纴闾d箞鎴戜滑鍙浠ョ湅鍒癴lush杩囩殑鏁版嵁
//骞朵笖session涓璭xistsInDatebase鐘舵佷负true </span>
session.flush();
//鎻愪氦浜嫔姟
//榛樿ゆ儏鍐典笅commit镎崭綔浼氩厛镓ц宖lush娓呯悊缂揿瓨锛屾墍浠ヤ笉鐢ㄦ樉绀虹殑璋幂敤flush
//commit钖庢暟鎹鏄镞犳硶锲炴粴镄
tx.commit();
}catch(Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testSave2() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
User2 user = new User2();
user.setName("寮犱笁1");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
//锲犱负user镄勪富阌鐢熸垚绛栫暐涓簄ative,镓浠ヨ皟鐢╯ession.save钖庯纴灏嗘墽琛宨nsert璇鍙ワ纴杩斿洖链夋暟鎹搴撶敓鎴愮殑id
//绾冲叆浜唖ession镄勭$悊锛屼慨鏀逛简session涓璭xistsInDatebase鐘舵佷负true
//濡傛灉鏁版嵁搴撶殑闅旂荤骇鍒璁剧疆涓烘湭鎻愪氦璇伙纴闾d箞鎴戜滑鍙浠ョ湅鍒皊ave杩囩殑鏁版嵁
session.save(user);
tx.commit();
}catch(Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
HibernateUtils.closeSession(session);
}
} </span>