高效SQL查询之索引(I)
大型系统的生产环境,一般情况下,我们评价一条查询是否有效率,更多的是关注逻辑 IO( 至于为什么,回头补一篇 ) 。我们常说,“要建彪悍的索引”、“要写高效的 SQL ”,其实最终目的就是在相同结果集情况下,尽可能减少逻辑 IO 。
1.1 where 条件的列上都得有统计信息。
没统计信息 SQLServer 就无法估算不同查询计划开销优劣,而只能采用最稳妥的 Scan (不管是 table scan 还是 clustered index scan )。一般情况下我们不会犯这种错误—— where 条件里不使用非索引列是个常识。索引上的统计信息是无法删除的。
1.2 尽量不使用不等于( != )或者 NOT 逻辑运算符。
这条规则被广为传颂,原因据联机文档和百敬同学的书讲,也是 SQLServer 无法评估不同查询计划开销的优劣。但是 SqlServer2k5 聪明了很多,试验发现尽管用了 != 或者 not ,查询还是会被优化。如下:
create table tb1
(
col1 int identity ( 1, 1) primary key ,
col2 int not null,
col3 varchar ( 64) not null
)
create index ix_tb1_col2 on tb1
(
col2
)
create index ix_tb1_col3 on tb1
(
col3
)
declare @f int
set @f = 0
while @f < 9999
begin
insert into tb1 ( col2, col3) values ( 1, 'ssdd' )
set @f = @f + 1
end
insert into tb1 ( col2, col3) values ( 0, 'aadddd' )
insert into tb1 ( col2, col3) values ( 2, 'bbddd' )
insert into tb1 ( col2, col3) values ( 3, 'bbaaddddddaa' )
通过上述代码,各位可以看到数据分布。 col2 值为 1 的有 9999 条; col2 值为 0 、 2 、 3 的分别有 1 条。
按照本条规则, != 和 NOT 带来的应该是个 scan 操作,但实际情况是:
SQL2k5 很聪明,它依据统计信息分析得出来,应该采用 index seek 而不是 index scan 。(稍微解释解释 index seek 和 index scan :索引是一颗 B 树, index seek 是查找从 B 树的根节点开始,一级一级找到目标行。 index scan 则是从左到右,把整个 B 树遍历一遍。假设唯一的目标行位于索引树(假设是非聚集索引,树深度 2 ,叶节点占用 k 页物理存储)最右的叶节点上(如上例)。
相关文档:
今天在配置数据库发布和分发时总是报出现 18483 错误
提示说:错误 18483:未能连接到服务器 "XXX",因为 'distributor_admin'未在该服务器上定义为远程登陆。
我的发布和分发是同一个服务器,"XXX" 为我的机器名,分发数据库是默认的名称,而我在另外一台机器上做时就正常。
1、设置共享复制目录:
......
SQL 2005 的存储过程和触发器调试大法(原创)
www.chengchen.net 程晨
昨天晚上我找遍了互联网也没有发现关于SQL2005存储过程和触发器的调试方法,研究到凌晨2点多钟,终于找到方法了,不干独享,拿出来分享。如果要转载,请保留版权,谢谢!
&nbs ......
定义和用法
DATEDIFF() 函数返回两个日期之间的天数。
语法
DATEDIFF(datepart,startdate,enddate)
startdate 和 enddate 参数是合法的日期表达式。
datepart 参数可以是下列的值:
datepart
缩写
年
yy, yyyy
季度
qq, q
月
mm, m
年中的日
dy, y
日
dd, d
周
wk, ww
星期
dw, w
小时
h ......
作中数据库经常出错死锁,并且还要要求解决当前的死锁,问题多多;
参照CSDN,中国风(Roy)一篇死锁文章并改进了下;
/***********************************************************************************************************************
整理人:黑木崖上的蜗牛(lenolotus) 日期:2009.04.28
************ ......