高效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 页物理存储)最右的叶节点上(如上例)。
相关文档:
一、 PL/SQL语言简介
(本讲义之所有程序均调式通过)
首先我们看一个简单之例子,下面这个例子是统计从1至100的总和.
declare
i number:=0; /*声明变量井给初值*/
t number:=1;
error_message exception; /*声明一个出错处理*/
begin
......
作中数据库经常出错死锁,并且还要要求解决当前的死锁,问题多多;
参照CSDN,中国风(Roy)一篇死锁文章并改进了下;
/***********************************************************************************************************************
整理人:黑木崖上的蜗牛(lenolotus) 日期:2009.04.28
************ ......
今天做SQL 优化,查找执行计划时,执行计划,发现此执行计划与以往的计划有所区别;找录互联网,终于找一篇有关研究比较深入的文章;
原执行计划使用的是索引扫描,突然一下会使用索引覆盖技术,效率大增;
SELECT * 的真相:索引覆盖(index coverage)
SELECT *的效率很糟糕吗?当然,所有人都知道这一点,但是为什么 ......
先站在应用程序的角度说说它们的不同。
1、 直接拼 SQL
就像大家了解的那样,直接拼 SQL 带来了 SQL 注入攻击,带来了拼时些许的性能损失,但是拼不用添加 SqlParameter ,会少写很多代码——很多人喜欢直接拼,也许就因为这点。这种做法会把你拼好的 SQL 原样直接发送到 DB 服务器去执行。(注意类似 &rdquo ......