• 主页
  • 基础类
  • 应用实例
  • 新技术前沿

求SQL语句优化

Eri 2008-01-23 03:31:30
select *
from t_weblog a where bk_abbPaytime between '2008-01-13' and '2008-01-19'
and bk_payCode not in(select bk_paycode from t_banklog a
where bk_abbPaytime between '2008-01-13' and '2008-01-19')

每一个查询单独查的话速度都在0秒,就是Not In的时候要几分钟。
求一下语句上面的优化。
...全文
186 点赞 收藏 32
写回复
32 条回复
tim_spac 2008年01月26日
楼主:要不请教一下邹老大关于这个索引使用方式诡异情况的原因?
回复 点赞
ojuju10 2008年01月25日

在相应的字段上建立索引
回复 点赞
SeerMi 2008年01月25日
select a.*
from t_weblog a ,t_welog as b
where a.bk_abbPaytime between '2008-01-13' and '2008-01-19'
and a.bk_payCode=b.bk_paycode and (b.bk_abbpaytime<'2008-01-13' or b.bk_abbpaytime>'2008-01-19')

这样快不? :)
回复 点赞
Eri 2008年01月24日
现在发现新问题, 1号到14号的查询就飞快10秒左右,数据量比
13号到19号还大一倍左右,但是13号到19号查询就需要5分钟。
请问谁能帮忙分析原因。
回复 点赞
Eri 2008年01月24日
to birdie_mas
确实多数据了……

to dawugui
如果要改善查询效率应该怎么下手呢?
回复 点赞
cxmcxm 2008年01月24日
not in 换为not exists对相关的字段建索引
回复 点赞
chengg0769 2008年01月24日
bk_paycode没有索引或者not in造成没走索引吧。
=========================================
pb11&SQL QQ群: 6539042
回复 点赞
TNT_1st_excellence 2008年01月24日
建议:如果是资料量大,行列都很多,最好不要直接下SELECT语法,存储过程首先要优化一点,再在存储过程中优化.
回复 点赞
Eri 2008年01月24日
我也不知道,
我现在唯一知道的就是在我这个语句里使用了聚集索引速度速度提高几十倍……
我怀疑是因为聚居索引和非聚集索引中有字段是一致导致。
回复 点赞
tim_spac 2008年01月24日
是啊,我看了。我是不能理解为什么MSSQL会根据参数值的不同而选择不同的索引。不知道是它太智能了还是太弱智了。
理论上,查询时选择什么索引查询者不必干涉,系统会根据表达式来选择优化的方案;但按你说的情况看,系统还要看参数是什么来选择索引?太不可思议了!
回复 点赞
utpcb 2008年01月24日
检查索引碎片DBCC SHOWCONTIG(表)

逻辑扫描碎片和扩展盘区扫描碎片都非常大,需要对索引碎片进行处理


一般有两种方法解决,一是利用DBCC INDEXDEFRAG整理索引碎片,二是利用DBCC DBREINDEX重建索引。二者各有优缺点。调用微软的原话如下:
DBCC INDEXDEFRAG 命令是联机操作,所以索引只有在该命令正在运行时才可用。而且可以在不丢失已完成工作的情况下中断该操作。这种方法的缺点是在重新组织数据方面没有聚集索引的除去/重新创建操作有效。

重新创建聚集索引将对数据进行重新组织,其结果是使数据页填满。填满程度可以使用 FILLFACTOR 选项进行配置。这种方法的缺点是索引在除去/重新创建周期内为脱机状态,并且操作属原子级。如果中断索引创建,则不会重新创建该索引。

也就是说,要想获得好的效果,还是得用重建索引,所以决定重建索引。
DBCC DBREINDEX(表, 索引名, 填充因子)
第一个参数,可以是表名,也可以是表ID。
第二个参数,如果是'',表示影响该表的所有索引。
第三个参数,填充因子,即索引页的数据填充程度。如果是100,表示每一个索引页都全部填满,此时select效率最高,但以后要插入索引时,就得移动后面的所有页,效率很低。如果是0,表示使用先前的填充因子值。

DBCC DBREINDEX(A, '', 100)
重新测试查询速度,飞快。

回复 点赞
Eri 2008年01月24日
再看看我前面说的,我发现是使用的索引不一致导致的。
回复 点赞
tim_spac 2008年01月24日
两次查询(1~19 & 13~19)的脚本仅是时间参数值的差异?
不可能吧?
不可理解。
不可思议!
回复 点赞
Eri 2008年01月24日
bk_abbPaytime 加上另外两个字段(3字段做联合主键)
回复 点赞
Eri 2008年01月24日
重建了。
我用执行计划查看了一下,发现查询1号到19号的语句使用上了聚集索引 bk_abbPaytime 加上另外连个字段(主键),
而13号到19号的却使用了另外一个非聚集索引 bk_abbPaytime。

不知道为什么会这样。
是修改索引呢,还是指定使用聚集索引呢?
回复 点赞
tim_spac 2008年01月24日
重建索引
回复 点赞
Eri 2008年01月24日
check完了,是有1个错误,不过这个错误是2007年的数据。
修复完了以后13号到19号的查询时间缩短为2分钟了,还是很慢。
非常奇怪, 查1号到19号的时间都比中间一段13号到19号还快。
回复 点赞
tim_spac 2008年01月24日
dbcc checktable
回复 点赞
dawugui 2008年01月23日
select *
from t_weblog a where bk_abbPaytime between '2008-01-13' and '2008-01-19'
and bk_payCode not in(select bk_paycode from t_banklog a
where bk_abbPaytime between '2008-01-13' and '2008-01-19')


--
个人认为你的语句没得什么可优化的了.
回复 点赞
birdie_mas 2008年01月23日
這個也有問題,會多出數據的
回复 点赞
发动态
发帖子
MS-SQL Server
创建于2007-09-28

1.4w+

社区成员

25.3w+

社区内容

MS-SQL Server相关内容讨论专区
社区公告
暂无公告