我有一堆列表,是拆开一条一条执行效率高,还是凑成一句SQL执行效率高?

iorikingdom 2010-02-24 07:26:04
我有一堆列表,是拆开一条一条执行效率高,还是凑成一句SQL执行效率高?
例如我有a,b,c。。。。。n个字符串

然后执行
SELECT *FROM shoushou WHERE NB IN(a,b,c。。。。。n);
这样一种方式

另外一种方式是

SELECT *FROM shoushou WHERE NB='a';
SELECT *FROM shoushou WHERE NB='b';
SELECT *FROM shoushou WHERE NB='c';
SELECT *FROM shoushou WHERE NB='d';

.............................

SELECT *FROM shoushou WHERE NB='n';

哪种方式效率高?或者还有没有更好的方式?

...全文
291 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
fengyqf 2010-02-26
  • 打赏
  • 举报
回复
一楼正解
应该是SELECT *FROM shoushou WHERE NB IN('a','b','c'。。。。。'n');
iorikingdom 2010-02-26
  • 打赏
  • 举报
回复
感谢各位兄弟关注
索引是有的,我在想,因为如果用IN的话,估计会一个一个扫描找
但是如果用=的话,可能会用二分法查找,可能会快一点,数据还没有出来,
程序还没有完成,数据结构还在构造,目前还没有测试到实际结果
Barton 2010-02-26
  • 打赏
  • 举报
回复
顶下 up
up
  • 打赏
  • 举报
回复
分两种情况看

1). 有合适索引的情况,这个两者差不多.

2). 无索引或索引不中的情况,这个并成一句效率就高很多,因为一次扫描就可带出所有的结果。
我赞成这句话
  • 打赏
  • 举报
回复
具体看查询计划,这个说不好
ACMAIN_CHM 2010-02-25
  • 打赏
  • 举报
回复
SELECT *FROM shoushou WHERE NB='a';
SELECT *FROM shoushou WHERE NB='b';
SELECT *FROM shoushou WHERE NB='c';
SELECT *FROM shoushou WHERE NB='d';


这种方式高。
starseeker7 2010-02-25
  • 打赏
  • 举报
回复
可能是我數據量不苟 - -?
或許要千萬級別才比較看出來比較明顯
不過之前看過一篇文章有說

union all 這種分割
一般是在查詢條件為不同字段的時候的,,切割合併會有明顯的提高效率,
如果同一字段則不然
starseeker7 2010-02-25
  • 打赏
  • 举报
回复
恩我拿公司數據庫測試了下
select count(*) from dgmocpb --190000左右
select top 1 * from dgmocpb --50個字段
--PB039為日期格式的聚合索引
--每天數據量分佈平均,一下使測試數據


dbcc freeproccache
dbcc dropcleanbuffers
set statistics time on
select * from dgmocpb where pb039='2010-02-01'
union all
select * from dgmocpb where pb039='2010-02-02'
union all
select * from dgmocpb where pb039='2010-02-03'
union all
select * from dgmocpb where pb039='2010-02-04'
union all
select * from dgmocpb where pb039='2010-02-05'
set statistics time off
/*
DBCC 的執行已經完成。如果 DBCC 印出錯誤訊息,請聯絡您的系統管理員。
DBCC 的執行已經完成。如果 DBCC 印出錯誤訊息,請聯絡您的系統管理員。

(2016 個資料列受到影響)

SQL Server 執行次數:
CPU 時間 = 16 ms, 經過時間 = 1214 ms。
*/

dbcc freeproccache
dbcc dropcleanbuffers
set statistics time on
select * from dgmocpb where pb039>='2010-02-01' and pb039<='2010-02-05'
set statistics time off
/*
DBCC 的執行已經完成。如果 DBCC 印出錯誤訊息,請聯絡您的系統管理員。
DBCC 的執行已經完成。如果 DBCC 印出錯誤訊息,請聯絡您的系統管理員。
SQL Server 剖析與編譯時間:
CPU 時間 = 0 ms,經過時間 = 1 ms。

(2016 個資料列受到影響)

SQL Server 執行次數:
CPU 時間 = 0 ms, 經過時間 = 1354 ms。
*/

dbcc freeproccache
dbcc dropcleanbuffers
set statistics time on
select * from dgmocpb where pb039 in ('2010-02-01','2010-02-02',
'2010-02-03','2010-02-04','2010-02-05'
)
set statistics time off
/*
DBCC 的執行已經完成。如果 DBCC 印出錯誤訊息,請聯絡您的系統管理員。
DBCC 的執行已經完成。如果 DBCC 印出錯誤訊息,請聯絡您的系統管理員。

(2016 個資料列受到影響)

SQL Server 執行次數:
CPU 時間 = 0 ms, 經過時間 = 1285 ms。
*/


- -額貌似in 效率還高點?!
黄_瓜 2010-02-25
  • 打赏
  • 举报
回复
是不是我建立的索引不合适?请高手指点
黄_瓜 2010-02-25
  • 打赏
  • 举报
回复
if object_id('id') is null drop table tb
go
create table tb(id int, name varchar(1),date datetime)

insert into tb select rand()*10,char(cast(rand()*26+97 as int)),getdate()
go 1000000 --产生100百万测试数据.这个效率很低,但是我很懒
--创建索引
create index ix_name on tb(name)
--清空缓存
checkpoint
dbcc freeproccache
dbcc dropcleanbuffers
--测试in的时间

set statistics time on

SELECT *FROM tb with (index=ix_name) WHERE name IN('a','b','c','d')

set statistics time off
/*
(153362 行受影响)
SQL Server 执行时间:
CPU 时间 = 594 毫秒,占用时间 = 5398 毫秒。
*/
--测试并行
--再次清空缓存
checkpoint
dbcc freeproccache
dbcc dropcleanbuffers

set statistics time on
--SELECT *FROM tb WHERE name IN('a','b','c','d')

SELECT * FROM tb with (index=ix_name) WHERE name='a'
union all
SELECT * FROM tb with (index=ix_name) WHERE name='b'
union all
SELECT * FROM tb with (index=ix_name) WHERE name='c'
union all
SELECT * FROM tb with (index=ix_name) WHERE name='d'

set statistics time off
/*
SQL Server 执行时间:
CPU 时间 = 548 毫秒,占用时间 = 1942 毫秒。
*/

--不强制使用索引,它仍走的是表扫描
--强制试用索引,in所消耗的时间明显增加,第二种时间到有所减少
快乐_石头 2010-02-25
  • 打赏
  • 举报
回复
引用 11 楼 beirut 的回复:
当然我都没有建立索引

建立索引再看看呢~~~
Garnett_KG 2010-02-25
  • 打赏
  • 举报
回复
分两种情况看

1). 有合适索引的情况,这个两者差不多.

2). 无索引或索引不中的情况,这个并成一句效率就高很多,因为一次扫描就可带出所有的结果。

feixianxxx 2010-02-25
  • 打赏
  • 举报
回复
继续帮 up 。。。。。。。。。。。
黄_瓜 2010-02-25
  • 打赏
  • 举报
回复
当然我都没有建立索引
黄_瓜 2010-02-25
  • 打赏
  • 举报
回复
if object_id('id') is null drop table tb
go
create table tb(id int, name varchar(1),date datetime)

insert into tb select rand()*10,char(cast(rand()*26+97 as int)),getdate()
go 1000000 --产生100百万测试数据.这个效率很低,但是我很懒

--测试in的时间
set statistics time on

SELECT *FROM tb WHERE name IN('a','b','c','d')

set statistics time off
/*
(153362 行受影响)


SQL Server 执行时间:
CPU 时间 = 969 毫秒,占用时间 = 1995 毫秒。
(153362 行受影响)

*/
--测试二
set statistics time on

SELECT * FROM tb WHERE name='a'
union all
SELECT * FROM tb WHERE name='b'
union all
SELECT * FROM tb WHERE name='c'
union all
SELECT * FROM tb WHERE name='d'

set statistics time off
/*

SQL Server 执行时间:
CPU 时间 = 1609 毫秒,占用时间 = 2037 毫秒。

*/
快乐_石头 2010-02-25
  • 打赏
  • 举报
回复
--很明顯拆分得到是多個結果集合
--覺得樓主應該比較的是這樣
SELECT *FROM shoushou WHERE NB IN('a','b','c','d')
--與
SELECT *FROM shoushou WHERE NB='a'
union all
SELECT *FROM shoushou WHERE NB='b'
union all
SELECT *FROM shoushou WHERE NB='c'
union all
SELECT *FROM shoushou WHERE NB='d'
--樓主可以在NB建立索引測試下看看
feixianxxx 2010-02-25
  • 打赏
  • 举报
回复
自己试试吧。。。
看看4楼
xmlxslt 2010-02-25
  • 打赏
  • 举报
回复
引用 18 楼 starseeker7 的回复:
union all 這種分割
一般是在查詢條件為不同字段的時候的,,切割合併會有明顯的提高效率,
如果同一字段則不然

对,LZ就用in吧,也简单
feixianxxx 2010-02-25
  • 打赏
  • 举报
回复
继续帮UP 。。。

感觉差不多
鸭梨山大帝 2010-02-24
  • 打赏
  • 举报
回复
1.凑成一句SQL执行效率高

2.不推荐77的拆分成表进行连接查询,因为增加了拆分时间,其拆分出来的表也不会有索引的.
直接拼串是最快的.

引用 3 楼 sql77 的回复:
例如我有a,b,c。。。。。n个字符串

然后执行
SELECT *FROM shoushou WHERE NB IN(a,b,c。。。。。n);

应该把a,b,c。。。。。n
拆分(可参见字符拆分精华)成一个表,连接查询

SQL codeSELECT*FROM shoushou TWHEREEXISTS(SELECT1FROM 拆分表WHERE A=T.NB)
加载更多回复(5)

34,576

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧