动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 数据库 > Oracle教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
数据库:数据库教程,数据库技巧,Oracle教程,MySQL教程,Sybase教程,Access教程,DB2教程,数据库安全,数据库文摘
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Oracle教程 ]的信息

本月文章推荐
.Java调用Oracle的过程和函数.
.Oracle里的交叉SQL语句写法.
.Oracle数据库用VPD来确保信息的隐.
.我的学习总结: Oracle软件结构.
.在Oracle中获取磁盘空间的使用情.
.Oracle中将数字转化成字符串.
.Oracle9i 性能调整与优化(2).
.ORACLE中的日志值转换成time_t.
.Oracle常用技巧和脚本技术应用.
.详细讲解获得当前"SCN"的几种有效.
.stty使用方法.
.oracle 数据分页查询.
.Oracle Database 10g:最佳新特性.
.ExactPapers Oracle 1Z0-147 200.
.DataGuard数据库服务器硬盘故障处.
.索引在ORACLE数据库中的应用分析.
.Oracle案例:日志组处于高激活状.
.快速掌握重启Oracle数据库的操作.
.关于连接池.
.[tip] pass 1z0-033 Oracle9i Pe.

一句T-SQL语句引发的思考 转帖

发表日期:2008-2-9 |



  关于MS SQLSERVER索引优化问题:
  有表Stress_test(id int, key char(2))
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]id 上有普通索引;
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]key 上有簇索引;
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]id 有有限量的重复;
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]key 有无限量的重复;
  
  现在我需要按逻辑与查询表中key='Az' AND key='Bw' AND key='Cv' 的id
  
  求教高手最有效的查询语句
  
  测试环境:
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Hardware:P4 2.6+512M+80G
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Software:windows server 2003(Enterprise Edition)+Sqlserver 2000 +sp3a
  
  [$nbsp][$nbsp]首先我们建立一个测试的数据,为使数据尽量的分布和随即,我们通过RAND()来随机产生2个随机数再组合成一个字符串,首先插入的数据是1,000,000条记录,然后在循环插入到58,000,000条记录。
  [$nbsp][$nbsp][$nbsp]因为是随机产生的数据,所以假如你自己测试的数据集和我测试的会不一样,但对索引的优化和运行的效率是一样的。
  [$nbsp][$nbsp][$nbsp]下面的“--//测试脚本”是产生测试数据的脚本,你可以根据需要修改 @maxgroup, @maxLoop的值,比如测试1百万的记录可以:
  
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Select @maxgroup=1000
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Select @maxLoop=1000
  
  假如要测试5千万:
  
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Select @maxgroup=5000
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Select @maxLoop=10000
  
  所以假如你的SERVER或PC比较慢,请耐心等待.....,
  (在我的PC上运行的速度是插入1百万条的时间是1.14m,插入5千八百万条的时间是19.41m,重新建立INDEX的时间是34.36m)
  
  
  
  作为一般的开发人员很轻易就想到的语句:
  
  [$nbsp][$nbsp][$nbsp]--语句1
  
  [$nbsp][$nbsp][$nbsp][$nbsp]select a.[id] from
  [$nbsp][$nbsp][$nbsp][$nbsp](select distinct [id] from stress_test where [key] = 'Az') a,
  [$nbsp][$nbsp][$nbsp][$nbsp](select distinct [id] from stress_test where [key] = 'Bw') b ,
  [$nbsp][$nbsp][$nbsp][$nbsp](select distinct [id] from stress_test where [key] = 'Cv') c
  [$nbsp][$nbsp][$nbsp][$nbsp]where a.id = b.id and a.id = c.id
  
  [$nbsp][$nbsp][$nbsp]--语句2
  
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]select [id]
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]from stress_test
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]where [key]='Az' or [key]='Bw' or [key]='Cv'
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]group by id having(count(distinct [key])=3)
  
  [$nbsp][$nbsp][$nbsp]--语句5
  
  [$nbsp][$nbsp][$nbsp][$nbsp]SELECT distinct a.[id] FROM stress_test AS a,stress_test AS b,stress_test AS c
  [$nbsp][$nbsp][$nbsp][$nbsp]WHERE a.[key]='Az' AND b.[key]='Bw' AND c.[key]='Cv'
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]AND a.[id]=b.[id] AND a.[id]=c.[id]
  
  但作为T-SQL的所谓“高手”可能会认为这种写法很“土”,也显得没有水平,所以会选择一些子查询和外连接的写法,按常理子查询的效率是比较高的:
  
  [$nbsp][$nbsp][$nbsp]--语句3
  
  [$nbsp][$nbsp][$nbsp][$nbsp]select distinct [id] from stress_test A where
  [$nbsp][$nbsp][$nbsp][$nbsp]not exists (
  [$nbsp][$nbsp][$nbsp][$nbsp]select 1 from
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp](select 'Az' as k union all select 'Bw' union all select 'Cv') B
  [$nbsp][$nbsp][$nbsp][$nbsp]left join stress_test C on C.id=A.id and B.[k]=C.[key]
  [$nbsp][$nbsp][$nbsp][$nbsp]where C.id is null)
  
  [$nbsp][$nbsp][$nbsp]--语句4
  
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]select distinct a.id from stress_test a
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]where not exists
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]( select * from keytb c
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]where not exists
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]( select * from stress_test b
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]where
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]b.id = a.id
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]and
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]c.kf1 = b.[key]
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp])
  [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp])
  
  我们先分析这几条语句(针对5千8百万条数据进行分析):
  
  请大家要非凡留心Estimated row count的值。

  
  语句1:从执行规划中我们可以看出,MSSQLSERVER选择的索引优化非常有规律,先通过CLUSTERED INDEX筛选出符合[KEY]='Az'条件的ID,然后进行HASH MATCH,在找出ID相等的;依次类推最终检索到符合所有条件的记录。中间的Estimated row count的值都不大。
  
  语句2:从执行规划中我们可以看出,是先通过CLUSTERED INDEX筛选出符合 [key]='Az' or [key]='Bw' or [key]='Cv' 符合所有条件的ID,然后分组进行2次HASH MATCH 所有的ID。我们可以看出Estimated row count的值是越来越少,从最初的369,262到最后排序的只有402。
  
  语句3:从执行规划中我们可以看是非常复杂的,是先通过3组 通过CONSTANT SCAN和NON-CLUSTERED INDEX检索出符合 A.ID=C.ID AND [key]='**' 的记录3组,然后分组进行外键匹配,再将3组的数据合并,排序,然后再和一个NON-CLUSTERED INDEX检索出的记录集进行外键匹配,我们可以看出MSSQLSERVER会对所有的记录(5千万条)记录进行分组,Estimated row count的值是:58,720,000,所以这句T-SQL的瓶颈是对5千万条记录进行分组。
  
  语句4:从执行规划中我们可以看和语句3有相似之处,都要对所有的记录(5千万条)记录进行分组,所以这是检索的瓶颈,而且使用的索引都是NON-CLUSTERED INDEX。
  
  语句5:从执行规划中我们可以看出,先通过CLUSTERED INDEX检索出符合[Key]='Az'的记录集,然后进行HASH MATCH和SORTS,因为数量少所以是非常会的,在和通过NON-CLUSTERED INDEX检索[KEY]='Bw'的记录进行INNER JOIN,在和通过CLUSTERED INDEX检索[KEY]='Cv'的记录进行合并,最后是对4百万条数据进行分组检索,假如是6列,我们可以看出Estimated row count的值是递增,越来越大,最后的分组检索的Estimated row count的值是3.46E+15,这已经形成巨大的瓶颈。
  
  我们可以先测试一下小的数据量(50000条);
  
  大家可以下面测试脚本的:
  
  [$nbsp][$nbsp][$nbsp]Select @maxgroup=500
  [$nbsp][$nbsp][$nbsp]Select @maxLoop=100
  
  ----------------------------------------------------------------------
  ------------------语句 1----语句 2----语句 3----语句 4----语句 5----
   5万(3列) 5ms 19ms 37ms 59ms 0ms
   5万(6列) 1ms 26ms 36ms 36ms 1ms
  
  
  从测试的的数据来看,语句5的效率是最高的,几乎没有花费时间,而语句2的效率只能说是一般。假如测试到这里就结束了,我们可以毫不犹豫的选择语句 5 :-(,继续进行下面的测试.....
  
  我们测试百万条以上的记录:
  1.先对1百万条记录进行测试(选取3列)
  2.先对1百万条记录进行测试(选取6列)
  3.对5千万条数据测试(选取3列)
  4.对5千万条数据测试(选取6列)
  
  统计表1:
  ----------------------------------------------------------------------
  ------------------语句 1----语句 2----语句 3----语句 4----语句 5----
   1百万(3列) 0.77% 0.41% 49.30% 48.99% 0.52%
   1百万(6列) 1.61% 0.81% 48.99% 47.44% 1.14%
   5千万(3列) 0.14% 0.18% 48.88% 48.86% 1.93%
   5千万(6列) 0.00% 0.00% 0.00% 0.00% 100.00%
  统计表2:
  ----------------------------------------------------------------------
  ------------------语句 1----语句 2----语句 3----语句 4----语句 5----
   1百万(3列) 9ms 22ms 723ms 753ms 4ms
   1百万(6列) 15ms 38ms 764ms 773ms 11ms
   5千万(3列) 575ms 262ms 110117ms 110601ms 12533ms
   5千万(6列) 1070ms 576ms 107988ms 109704ms 10m以上
  
  测试总结:(我们可以比较关注:语句 2和语句 5)
  1.在1百万条记录的情况下,语句 5是最快的,但在5千万条记录下是最慢的。这说明INDEX的优化一定的情况下,数据量不同,检索的效率也是不同的。我们
上一篇:isql*plus中经常使用修改select语句的语法 人气:644
下一篇:Oracle10g中新的SQLoptimizerhints 人气:445
浏览全部Oracle教程的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-10-7 Web Wiz Forums(论坛系统) v9.53
2008-10-7 Web Wiz Forums(论坛系统) v9.53
2008-10-7 Web Wiz Forums(论坛系统) v9.53
2008-10-7 HDWiki v4.0.1 bulid 081007 UTF
2008-10-7 迅易评选投票管理系统 v10.0
2008-10-7 HDWiki v4.0.1 bulid 081007 GBK
2008-10-7 Bitrac单用户博客 v1.14 bulid 0
2008-10-7 OpenX(广告管理系统) v2.6.2 多国
2008-10-7 乐铺网店系统免费普及版 v3.41
2008-9-29 酷狗音乐(原KuGoo)2008 v5.310 正
2008-9-29 QQTab 1.1
2008-9-29 网络传送带 Net Transport 2.64a
2008-9-29 谷歌金山词霸v1.8
2008-9-29 TweakVI 1.0 Build 1090
2008-9-29 ACDSee Pro 2.5 Build 333 汉化绿
2008-9-29 Winamp v5.541(2189) 周明波简体
2008-9-27 CCleaner 2.12.651
2008-9-27 Mozilla Thunderbird 2.0.0.17 英
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | js/vbs加密 | md5加密 | 进制转换 | UTF-8 转换工具 | Html转换js | Html转换asp | Html转换php | Html转换perl
实用工具:汉字翻译拼音 | 拼音字典 | 符号对照表 | 个税计算 | 实时汇率查询换算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 | 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵
SEO対策 中国語教室 ホームページ作成