数据库查询优化艺术
A. 数据库中查询优化的一般规律是什么
查询检索的优化首先想到你检索条件中的字段是不是索引字段,不是的话,建立索引
然后是sql语句的优化,select其实就是循环,循环的次数越多,检索效率越慢,子查询可以有,但是不要超过三层,超过三层,估计就是检索sql有问题,要重新梳理逻辑
避免笛卡尔积,几个表关联的时候,要用主键或者逻辑主键去关联
聚合函数的用法,要注意重复数据的过滤
where条件尽量写详细,条件越多,就能过滤掉更多的数据,这样就会提高效率
对于百万级别或者千万级别的数据量的检索,就不是sql优化那么简单了,要用到数据库本身的一些优化机制,有些数据库带有临时表,这是很好的优化方法
存储过程也是可以优化sql的,一些循环或者条件判断都可以用存储过程来实现
纯手打。。。。。。。。。。。。。。。。。。。。。。。。。大家可以补充
B. 怎样优化数据库查询怎样才能提高数据库的查询效率
网上有好多这方面的帖子,但我就不去找了。把我知道的几点给你列一下。
第一点:网速得给力,也就是应用服务器和数据库服务器之间不要做过多限制,特别是防火墙方面的,最好在一个网段
第二点:使用数据库连接池,无需创建连接,直接查询
第三点:查询语句上要明确指定查询那些列
第四点:连接查询,嵌套查询方面要仔细斟酌,选择最优的方案
第五点:分清各个函数、一些语法的特性,比如要分得清什么时候用 exists 什么时候用in
第六点:随着数据量的增大,再好的语句也会慢下来,可以考虑利用分区
。。。
其他方面还有,可以查看下论坛上的帖子总结一下
C. 怎么样操作数据库的查询优化技术
在一个关系数据库中提高和优化查询方法。很多人都将数据库看成神奇的圣人,即能够解决人们提出的各种问题。任何关系数据库都有一套解决查询的规则,而各种关系数据库查询的过程稍有所区别,但是基本的操作思想和过程是一致的。本文将为你介绍查询分析器解决查询的方法和过程。查询优化的目标在查看分析器查询的步骤之前,理解查询优化目标相当重要。显然,查询操作的其中一个目标是尽可能地减少使用资源。从数据库的角度看,这就意味着尽可能地减少I/O操作的次数。在对I/O操作的判断上,查询分析器经常做出错误的结果。而I/O操作次数必须满足磁盘的读取容量。这样从磁盘I/O读取的角度看,必须做出合理的选择条件。索引基于表格的索引是关系数据库用于解决查询的重要技术,也是数据库同时预先将数据分类导入到多表格的方式。通过索引中的字段和实际数据存放的指针可以完成以上的过程。除了集簇索引(Clustered Index),每一索引的使用都以磁盘容量作为代价。集簇索引是真正意义上与磁盘读取和磁盘容量代价无关的方法,因为集簇索引是真正按照顺序将数据存储到表格。当使用一个索引,数据库引擎必须执行两个数据读取,这两个数据读取是数据库记录所必需的。第一个数据被读取到实际数据指针的索引。第二个数据被读入到指针指定的位置。此时必须通过数据库服务器来查询,所以考虑系统资源消耗是有必要的。这也是查询分析器不使用索引的主要原因。在后面的部分中,即Covering Indices,你将学会不使用这两种读取的方法——然而,在很多时候使用索引即意味着每一记录可以完成两次读取。统计页统计页(Statistics page)是SQL Server用于决定是否使用索引时必需的信息。每一索引都有一个信息表,以将表格所有数据的索引关键值分布告诉查询优化器。统计页可用于大致估计从一个查询返回的行数。查询分析器必须知道返回的行数,由此确定是否值得使用索引方式。如果查询优化器从索引统计页中得知将返回几行,它就会选择使用索引;如果从统计页中得知将返回大数量的行数,索引查询优化器将有可能使用一个表扫描来解决查询。字段顺序当使用到索引时,字段顺序(Field order)代表众多字段的顺序。当判断是否使用索引时,服务器必须从第一字段到最后字段扫描。任何与查询无关的字段都将该索引清除掉。当进行索引安排时,你应该将最经常使用到的查询排列在索引最顶端,不属于查询范围的字段可以使查询优化器忽略整个索引。 使用WHERE语句WHERE语句是确定索引的选择语句的重要组成部分。WHERE语句过滤了显示记录的数量,也是查询优化器查找索引值的最容易的方法。WHERE语句的使用方法有很多种,以下为通常使用到的几种形式:匹配(相等)WHERE语句最为常用的例子就是一个记录或多个记录的匹配。当你指定一个特定字段等于一个值时,查询优化器将获知它要查询的索引入口,并识别满足查询条件的记录。这就大大地过滤读取记录的数量,从而减少查询所需要的时间。并且,查询分析器将可找到包含与匹配操作有关的字段索引的位置。大于或小于虽然匹配和相等是最为普通的选择方式,而WHERE语句中的查询范围要求也是经常见到的。在这种情况下,查询分析器获知大于或者小于指定值的索引范围。通常,查询分析器可从多个独立语句中确定被读取的索引百分含量,并决定是否值得使用索引技术。函数在WHERE语句中使用函数可以限制索引查询的范围。查询分析器的查询结果难于确定,尤其在执行非常量字段的时候。所以,使用WHERE语句的函数将尽可能减少查询次数。使用ORDER BY语句一旦查询分析器以WHERE语句来判断,它将以ORDER BY语句而开始查询。如果查询优化器找到正确顺序行的相应索引,并且这一索引与WHERE条件相符合,优化器将会直接使用到索引技术。为了方便使用索引,ORDER BY语句不应该包含不必要的字段。查询分析器不能识别一个字段的表面意思,而ORDER BY语句可实现按照字段来排序。由此,如果你的ORDER BY语句中包括字段,优化器将会找到包含所有这些字段的索引。在ORDER BY语句中列出每一字段将有效地阻止查询优化器使用索引。详细索引(Covering indices)以上我提到查询分析器使用索引也会带来负面,所以有时候我们将不使用索引技术,特别是对于已经确定顺序的索引。比如,如果你从一个用户记录中选择User ID,First Name,LastName以及EmailAddress,你可获得包含所有这些字段的一个索引,然后查询分析器可以直接使用索引并读取数据表。此时,使用一个双向对照表(cross reference table)将特别有用。你可以在一个方向上使用一个集簇索引,然后在相反方向建立一个带有字段的索引。这样SQL服务器的第一个方向上可以使用物理表查询,而在相反方向上使用到索引技术。由于长关键字的原因,详细索引需要额外的空间和更多的时间。然而,如果你有一个参考表,详细索引能够有助于查询分析器更好地工作。帮助查询优化器当你提交一个查询之后,查询分析器的执行都必须通过很多环节。这些环节将有助于快速地获得结果。然而,通过在查询中指定你所需要的内容和建立正确的索引,即帮助查询优化器的操作,以上过程才能顺利完成。
D. 网站数据库查询如何优化才能达到最佳速度
建议你这样试试看:
用多少数据就取多少数据原则
减少连表查询
给数据库经常查询的表加索引
优化数据库结构,减少不必要的查询
经常使用不经常更新的数据缓存起来
这样做的好处:优化数据库查询对于提高网站打开速度、减轻服务器压力非常重要。
注意事项:
1、对查询进行优化,应尽可能避免全表扫描
2、写数据语句时尽可能减少表的全局扫描
3、不要在条件判断时进行 算数运算
4、很多时候用 exists 代替 in 是一个好的选择
5 论索引技巧
E. 《数据库查询优化器的艺术原理解析与SQL性能优化》epub下载在线阅读,求百度网盘云资源
《数据库查询优化器的艺术》(李海翔)电子书网盘下载免费在线阅读
资源链接:
链接:
书名:数据库查询优化器的艺术
作者:李海翔
豆瓣评分:8.4
出版社:机械工业出版社
出版年份:2014-1-1
页数:532
内容简介:
《数据库技术丛书·数据库查询优化器的艺术:原理解析与SQL性能优化》是数据库查询优化领域的里程碑之作,由Oracle公司MySQL全球开发团队、资深专家撰写,作者有10余年数据库内核和查询优化器研究经验。数据库领域泰斗王珊教授亲自作序推荐,PostgreSQL中国社区和中国用户会发起人以及来自Oracle、新浪、网易、华为等企业的数位资深数据库专家联袂推荐。从原理角度深度解读和展示数据库查询优化器的技术细节和全貌;从源码实现角度全方位深入分析MySQL和PostgreSQL两大主流开源数据库查询优化器的实现原理;从工程实践的角度对比了两大数据库的查询优化器的功能异同和实现异同。它是所有数据开发工程师、内核工程师、DBA以及其他数据库相关工作人员值得反复研读的一本书。
《数据库技术丛书·数据库查询优化器的艺术:原理解析与SQL性能优化》共19章,分为四个部分:第一篇(第1~4章)对数据库查询优化技术的范围、逻辑查询优化、物理查询优化,以及查询优化器与其他模块的关系做了非常细致、深入的讲解;第二篇(第5~10章)首先从源码角度对PostgreSQL查询优化器的架构、层次、设计思想、相关数据结构和实现原理进行了深入、系统的分析,然后从功能角度对PostgreSQL的逻辑查询优化、物理查询优化、查询优化器的关键算法,以及PostgreSQL查询优化器与其他模块的关系做了深入的讲解;第三篇(第11~16章)首先从源码角度对MySQL查询优化器的架构、层次、设计思想、相关数据结构和实现原理进行了深入、系统的分析,然后从功能角度对MySQL的逻辑查询优化、物理查询优化、查询优化器的关键算法,以及MySQL查询优化器与其他模块的关系做了深入的讲解;第四篇(第17~19章)对PostgreSQL与MySQL的逻辑查询优化技术、物理查询优化技术、设计思想和编码规范等各方面进行了深度的比较。
作者简介:
李海翔,网名“那海蓝蓝”,资深数据库专家,从事数据库研发、数据库测试与技术管理等工作10余年,对数据库的内核有深入的研究,长于PostgreSQL和MySQL等开源数据库的内核与架构。现任职于Oracle公司MySQL全球开发团队,从事查询优化技术的研究和MySQL查询优化器的开发工作。曾参与了863、核高基、工信部、科技部、发改委、北京市科委等多个重大科技项目。2005年获得北京市科学技术进步奖一等奖,2006年获高级工程师(系统分析师)。
F. 数据库查询优化的策略有哪些
数据库查询操作在各种数据库操作中所占据的比重最大,而查询操作所基于的select语句在SQL语句中又是代价最大的语句。举例来说,如果数据的量积累到一定程度,比如一个银行的账户数据库表信息积累到上百万甚至上千条记录,全表扫描一次往往需要数十分钟,甚至数小时。如果采用比全表扫描更好的查询策略,往往可以使查询时间降为几分钟,由此可见查询优化技术的重要性。
G. 数据库查询优化器的艺术哪些人需要了解
基本上可以分成三大类(主流的):
1.大型数据库:如Oracle,DB2
2.中型数据库:如SQLServer,sybase
3.小型数据库:如MySQL
还有一些(没什么人用的)如:VF(foxpro),Access mdb ,infomix ,cloudscape
H. 数据库查询性能优化方式有哪些
1、1、调整数据结构的设计。这一部分在开发信息系统之前完成,程序员需要考虑是否使用ORACLE数据库的分区功能,对于经常访问的数据库表是否需要建立索引等。
2、2、调整应用程序结构设计。这一部分也是在开发信息系统之前完成,程序员在这一步需要考虑应用程序使用什么样的体系结构,是使用传统的Client/Server两层体系结构,还是使用Browser/Web/Database的三层体系结构。不同的应用程序体系结构要求的数据库资源是不同的。
3、3、调整数据库SQL语句。应用程序的执行最终将归结为数据库中的SQL语句执行,因此SQL语句的执行效率最终决定了ORACLE数据库的性能。ORACLE公司推荐使用ORACLE语句优化器(Oracle Optimizer)和行锁管理器(row-level manager)来调整优化SQL语句。
4、4、调整服务器内存分配。内存分配是在信息系统运行过程中优化配置的,数据库管理员可以根据数据库运行状况调整数据库系统全局区(SGA区)的数据缓冲区、日志缓冲区和共享池的大小;还可以调整程序全局区(PGA区)的大小。需要注意的是,SGA区不是越大越好,SGA区过大会占用操作系统使用的内存而引起虚拟内存的页面交换,这样反而会降低系统。
5、5、调整硬盘I/O,这一步是在信息系统开发之前完成的。数据库管理员可以将组成同一个表空间的数据文件放在不同的硬盘上,做到硬盘之间I/O负载均衡。
6、6、调整操作系统参数,例如:运行在UNIX操作系统上的ORACLE数据库,可以调整UNIX数据缓冲池的大小,每个进程所能使用的内存大小等参数。
实际上,上述数据库优化措施之间是相互联系的。ORACLE数据库性能恶化表现基本上都是用户响应时间比较长,需要用户长时间的等待。但性能恶化的原因却是多种多样的,有时是多个因素共同造成了性能恶化的结果,这就需要数据库管理员有比较全面的计算机知识,能够敏感地察觉到影响数据库性能的主要原因所在。另外,良好的数据库管理工具对于优化数据库性能也是很重要的。
ORACLE数据库性能优化工具
常用的数据库性能优化工具有:
1、1、ORACLE数据库在线数据字典,ORACLE在线数据字典能够反映出ORACLE动态运行情况,对于调整数据库性能是很有帮助的。
2、2、操作系统工具,例如UNIX操作系统的vmstat,iostat等命令可以查看到系统系统级内存和硬盘I/O的使用情况,这些工具对于管理员弄清出系统瓶颈出现在什么地方有时候很有用。
3、3、SQL语言跟踪工具(SQL TRACE FACILITY),SQL语言跟踪工具可以记录SQL语句的执行情况,管理员可以使用虚拟表来调整实例,使用SQL语句跟踪文件调整应用程序性能。SQL语言跟踪工具将结果输出成一个操作系统的文件,管理员可以使用TKPROF工具查看这些文件。
4、4、ORACLE Enterprise Manager(OEM),这是一个图形的用户管理界面,用户可以使用它方便地进行数据库管理而不必记住复杂的ORACLE数据库管理的命令。
5、5、EXPLAIN PLAN——SQL语言优化命令,使用这个命令可以帮助程序员写出高效的SQL语言。
ORACLE数据库的系统性能评估
信息系统的类型不同,需要关注的数据库参数也是不同的。数据库管理员需要根据自己的信息系统的类型着重考虑不同的数据库参数。
1、1、在线事务处理信息系统(OLTP),这种类型的信息系统一般需要有大量的Insert、Update操作,典型的系统包括民航机票发售系统、银行储蓄系统等。OLTP系统需要保证数据库的并发性、可靠性和最终用户的速度,这类系统使用的ORACLE数据库需要主要考虑下述参数:
l l 数据库回滚段是否足够?
l l 是否需要建立ORACLE数据库索引、聚集、散列?
l l 系统全局区(SGA)大小是否足够?
l l SQL语句是否高效?
2、2、数据仓库系统(Data Warehousing),这种信息系统的主要任务是从ORACLE的海量数据中进行查询,得到数据之间的某些规律。数据库管理员需要为这种类型的ORACLE数据库着重考虑下述参数:
l l 是否采用B*-索引或者bitmap索引?
l l 是否采用并行SQL查询以提高查询效率?
l l 是否采用PL/SQL函数编写存储过程?
l l 有必要的话,需要建立并行数据库提高数据库的查询效率
SQL语句的调整原则
SQL语言是一种灵活的语言,相同的功能可以使用不同的语句来实现,但是语句的执行效率是很不相同的。程序员可以使用EXPLAIN PLAN语句来比较各种实现方案,并选出最优的实现方案。总得来讲,程序员写SQL语句需要满足考虑如下规则:
1、1、尽量使用索引。试比较下面两条SQL语句:
语句A:SELECT dname, deptno FROM dept WHERE deptno NOT IN
(SELECT deptno FROM emp);
语句B:SELECT dname, deptno FROM dept WHERE NOT EXISTS
(SELECT deptno FROM emp WHERE dept.deptno = emp.deptno);
这两条查询语句实现的结果是相同的,但是执行语句A的时候,ORACLE会对整个emp表进行扫描,没有使用建立在emp表上的deptno索引,执行语句B的时候,由于在子查询中使用了联合查询,ORACLE只是对emp表进行的部分数据扫描,并利用了deptno列的索引,所以语句B的效率要比语句A的效率高一些。
2、2、选择联合查询的联合次序。考虑下面的例子:
SELECT stuff FROM taba a, tabb b, tabc c
WHERE a.acol between :alow and :ahigh
AND b.bcol between :blow and :bhigh
AND c.ccol between :clow and :chigh
AND a.key1 = b.key1
AMD a.key2 = c.key2;
这个SQL例子中,程序员首先需要选择要查询的主表,因为主表要进行整个表数据的扫描,所以主表应该数据量最小,所以例子中表A的acol列的范围应该比表B和表C相应列的范围小。
3、3、在子查询中慎重使用IN或者NOT IN语句,使用where (NOT) exists的效果要好的多。
4、4、慎重使用视图的联合查询,尤其是比较复杂的视图之间的联合查询。一般对视图的查询最好都分解为对数据表的直接查询效果要好一些。
5、5、可以在参数文件中设置SHARED_POOL_RESERVED_SIZE参数,这个参数在SGA共享池中保留一个连续的内存空间,连续的内存空间有益于存放大的SQL程序包。
6、6、ORACLE公司提供的DBMS_SHARED_POOL程序可以帮助程序员将某些经常使用的存储过程“钉”在SQL区中而不被换出内存,程序员对于经常使用并且占用内存很多的存储过程“钉”到内存中有利于提高最终用户的响应时间。
CPU参数的调整
CPU是服务器的一项重要资源,服务器良好的工作状态是在工作高峰时CPU的使用率在90%以上。如果空闲时间CPU使用率就在90%以上,说明服务器缺乏CPU资源,如果工作高峰时CPU使用率仍然很低,说明服务器CPU资源还比较富余。
使用操作相同命令可以看到CPU的使用情况,一般UNIX操作系统的服务器,可以使用sar –u命令查看CPU的使用率,NT操作系统的服务器,可以使用NT的性能管理器来查看CPU的使用率。
数据库管理员可以通过查看v$sysstat数据字典中“CPU used by this session”统计项得知ORACLE数据库使用的CPU时间,查看“OS User level CPU time”统计项得知操作系统用户态下的CPU时间,查看“OS System call CPU time”统计项得知操作系统系统态下的CPU时间,操作系统总的CPU时间就是用户态和系统态时间之和,如果ORACLE数据库使用的CPU时间占操作系统总的CPU时间90%以上,说明服务器CPU基本上被ORACLE数据库使用着,这是合理,反之,说明服务器CPU被其它程序占用过多,ORACLE数据库无法得到更多的CPU时间。
数据库管理员还可以通过查看v$sesstat数据字典来获得当前连接ORACLE数据库各个会话占用的CPU时间,从而得知什么会话耗用服务器CPU比较多。
出现CPU资源不足的情况是很多的:SQL语句的重解析、低效率的SQL语句、锁冲突都会引起CPU资源不足。
1、数据库管理员可以执行下述语句来查看SQL语句的解析情况:
SELECT * FROM V$SYSSTAT
WHERE NAME IN
('parse time cpu', 'parse time elapsed', 'parse count (hard)');
这里parse time cpu是系统服务时间,parse time elapsed是响应时间,用户等待时间
waite time = parse time elapsed – parse time cpu
由此可以得到用户SQL语句平均解析等待时间=waite time / parse count。这个平均等待时间应该接近于0,如果平均解析等待时间过长,数据库管理员可以通过下述语句
SELECT SQL_TEXT, PARSE_CALLS, EXECUTIONS FROM V$SQLAREA
ORDER BY PARSE_CALLS;
来发现是什么SQL语句解析效率比较低。程序员可以优化这些语句,或者增加ORACLE参数SESSION_CACHED_CURSORS的值。
2、数据库管理员还可以通过下述语句:
SELECT BUFFER_GETS, EXECUTIONS, SQL_TEXT FROM V$SQLAREA;
查看低效率的SQL语句,优化这些语句也有助于提高CPU的利用率。
3、3、数据库管理员可以通过v$system_event数据字典中的“latch free”统计项查看ORACLE数据库的冲突情况,如果没有冲突的话,latch free查询出来没有结果。如果冲突太大的话,数据库管理员可以降低spin_count参数值,来消除高的CPU使用率。
内存参数的调整
内存参数的调整主要是指ORACLE数据库的系统全局区(SGA)的调整。SGA主要由三部分构成:共享池、数据缓冲区、日志缓冲区。
1、 1、 共享池由两部分构成:共享SQL区和数据字典缓冲区,共享SQL区是存放用户SQL命令的区域,数据字典缓冲区存放数据库运行的动态信息。数据库管理员通过执行下述语句:
select (sum(pins - reloads)) / sum(pins) "Lib Cache" from v$librarycache;
来查看共享SQL区的使用率。这个使用率应该在90%以上,否则需要增加共享池的大小。数据库管理员还可以执行下述语句:
select (sum(gets - getmisses - usage - fixed)) / sum(gets) "Row Cache" from v$rowcache;
查看数据字典缓冲区的使用率,这个使用率也应该在90%以上,否则需要增加共享池的大小。
2、 2、 数据缓冲区。数据库管理员可以通过下述语句:
SELECT name, value FROM v$sysstat WHERE name IN ('db block gets', 'consistent gets','physical reads');
来查看数据库数据缓冲区的使用情况。查询出来的结果可以计算出来数据缓冲区的使用命中率=1 - ( physical reads / (db block gets + consistent gets) )。
这个命中率应该在90%以上,否则需要增加数据缓冲区的大小。
3、 3、 日志缓冲区。数据库管理员可以通过执行下述语句:
select name,value from v$sysstat where name in ('redo entries','redo log space requests');查看日志缓冲区的使用情况。查询出的结果可以计算出日志缓冲区的申请失败率:
申请失败率=requests/entries,申请失败率应该接近于0,否则说明日志缓冲区开设太小,需要增加ORACLE数据库的日志缓冲区。
I. 数据库查询有哪些优化方面
1 SQL查询语句的重写,对于一个查询可以用多种查询语句实现,但不同查询语句的数据库执行计划是不同的,一旦不能够使用索引或造成较大的内存占用会导致性能下降,因此需要对查询语句进行重写优化,最典型的例子就是not in语句使用外连接方式实现来进行优化
2 创建合理的索引结构,根据查询语句的中查询条件,在关系表上建立相应的索引,如B+树索引和hash索引
3 修改程序业务逻辑,有些功能如果使用SQL语句实现,不但SQL语句复杂,还将导致数据库的负担增加,因此可以将有些数据操作的业务逻辑放到应用层进行实现,就是通过java编程实现
4 修改数据库服务器相关参数,优化服务器性能
J. 如何优化数据库中数据的查询
1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。
3.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
4.in 和 not in 也要慎用,因为IN会使系统无法使用索引,而只能直接搜索表中的数据。如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
5.尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。
见如下例子:
SELECT * FROM T1 WHERE NAME LIKE ‘%L%’
SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’
SELECT * FROM T1 WHERE NAME LIKE ‘L%’
即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。
6.必要时强制查询优化器使用某个索引,如在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from t where num=@num
可以改为强制查询使用索引:
select id from t with(index(索引名)) where num=@num
7.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
SELECT * FROM T1 WHERE F1/2=100
应改为:
SELECT * FROM T1 WHERE F1=100*2
SELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=’5378’
应改为:
SELECT * FROM RECORD WHERE CARD_NO LIKE ‘5378%’
SELECT member_number, first_name, last_name FROM members
WHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21
应改为:
SELECT member_number, first_name, last_name FROM members
WHERE dateofbirth < DATEADD(yy,-21,GETDATE())
即:任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。
8.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id
应改为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
9.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
10.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
11.很多时候用 exists是一个好的选择:
elect num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)
SELECT SUM(T1.C1)FROM T1 WHERE(
(SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0)
SELECT SUM(T1.C1) FROM T1WHERE EXISTS(
SELECT * FROM T2 WHERE T2.C2=T1.C2)
两者产生相同的结果,但是后者的效率显然要高于前者。因为后者不会产生大量锁定的表扫描或是索引扫描。