SQL语句执行效率及分析(note)
in和exists的区别与SQL执行效率分析
in和exists的区别与SQL执行效率分析本文对in和exists的区别与SQL执行效率进行了全面整理分析……最近很多论坛又开始讨论in和exists的区别与SQL执行效率的问题,本文特整理一些in和exists的区别与SQL执行效率分析SQL中in可以分为三类:1、形如select * from t1 where f1 in ('a','b'),应该和以下两种比较效率select * from t1 where f1='a' or f1='b'或者select * from t1 where f1 ='a' union all select * from t1 f1='b'你可能指的不是这一类,这里不做讨论。
2、形如select * from t1 where f1 in (select f1 from t2 where t2.fx='x'),其中子查询的where里的条件不受外层查询的影响,这类查询一般情况下,自动优化会转成exist语句,也就是效率和exist一样。
3、形如select * from t1 where f1 in (select f1 from t2 where t2.fx=t1.fx),其中子查询的where里的条件受外层查询的影响,这类查询的效率要看相关条件涉及的字段的索引情况和数据量多少,一般认为效率不如exists。
除了第一类in语句都是可以转化成exists 语句的SQL,一般编程习惯应该是用exists而不用in,而很少去考虑in和exists的执行效率.in和exists的SQL执行效率分析A,B两个表,(1)当只显示一个表的数据如A,关系条件只一个如ID时,使用IN更快:select * from A where id in (select id from B)(2)当只显示一个表的数据如A,关系条件不只一个如ID,col1时,使用IN就不方便了,可以使用EXISTS:select * from Awhere exists (select 1 from B where id = A.id and col1 = A.col1)(3)当只显示两个表的数据时,使用IN,EXISTS都不合适,要使用连接:select * from A left join B on id = A.id所以使用何种方式,要根据要求来定。
SQL查询语句使用rand()的执行效率与优化
SQL查询语句使⽤rand()的执⾏效率与优化若要在i ≤ R ≤ j这个范围得到⼀个随机整数R,需要⽤到表达式 FLOOR(i + RAND() * (j – i + 1))。
例如,若要在7 到 12 的范围(包括7和12)内得到⼀个随机整数, 可使⽤以下语句:SELECT FLOOR(7 + (RAND() * 6));从 Mysql 表中随机读取数据不难,⽅法还挺多的,但是如果要考虑效率,得到⼀个快速的⾼效率的⽅法,那就不是⼀件简单的事情了(⾄少对我来说不简单)。
随机获得Mysql数据表的⼀条或多条记录有很多⽅法,下⾯我就以users(userId,userName,password……)表(有⼀百多万条记录)为例,对⽐讲解下⼏个⽅法效率问题:1. select * from users order by rand() LIMIT 1执⾏该sql语句,⽼半天没有反应,最后被迫⼿动停⽌执⾏,怎个伤⼈了得啊!后来我查了⼀下MYSQL⼿册,⾥⾯针对RAND()的提⽰⼤概意思就是,在 ORDER BY从句⾥⾯不能使⽤RAND()函数,因为这样会导致数据列被多次扫描,导致效率相当相当的低!效率不⾏,切忌使⽤!2. SELECT * FROM users WHERE userId >= ((SELECT MAX(userId) FROM users)-(SELECT MIN(userId) FROM users)) * RAND() +(SELECT MIN(userId) FROM users) LIMIT 1执⾏该sql语句,⽤时0.039s,效率太给⼒了!接着我就把”LIMIT 1“改为了”LIMIT 10000“,⽤时0.063s。
经过多次验证,结果肯定是随机的!结论:随机取⼀条或多条记录,⽅法都不错!3. 通过sql获得最⼤值和最⼩值,然后通过php的rand⽣成⼀个随机数randnum,再通过SELECT * FROM users WHERE userId >=randnum LIMIT 1,获得⼀条记录效率应该还可以,多条应该就不⾏了。
高效SQL语句5篇
高效SQL语句5篇第一篇:高效SQL语句1.SELECT子句中避免使用“*”当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL 列引用…*‟是一个方便的方法.不幸的是,这是一个非常低效的方法.实际上,ORACLE在解析的过程中, 会将“*” 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.2.使用DECODE函数来减少处理时间使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.例如:Sql代码1.SELECT COUNT(*),SUM(SAL)FROM EMP WHERE DEPT_NO = 0020 ANDENAME LIKE …SMITH%‟;2.SELECT COUNT(*),SUM(SAL)FROM EMP WHERE DEPT_NO = 0030 AND ENAME LIKE …SMITH%‟;SELECT COUNT(*),SUM(SAL)FROM EMP WHERE DEPT_NO = 0020 ANDENAME LIKE …SMITH%‟;SELECT COUNT(*),SUM(SAL)FROM EMP WHERE DEPT_NO = 0030 AND ENAME LIKE …SMITH%‟;你可以用DECODE函数高效地得到相同结果:Sql代码1.SELECT COUNT(DECODE(DEPT_NO,0020,‟X ‟,NULL))D0020_COUNT,2.COUNT(DECODE(DEPT_NO,0030,‟X ‟,NULL))D0030_COUNT,3.SUM(DECODE(DEPT_NO,0020,SAL,NUL L))D0020_SAL,4.SUM(DECODE(DEPT_NO,0030,SAL,NULL))D0030 _SAL5.FROM EMP WHERE ENAME LIKE …SMITH%‟;SELECT COUNT(DECODE(DEPT_NO,0020,‟X ‟,NULL))D0020_COUNT,COUNT(DECODE(DEPT_NO,0030,‟X ‟,NULL))D0030_COUNT,SUM(DECODE(DEPT_NO,0020,SAL,NULL))D0020_SAL,SUM(DECODE(DEPT_NO,0030,SAL,NULL))D0030_SA L FROM EMP WHERE ENAME LIKE …SMITH%‟;类似的,DECODE函数也可以运用于GROUP BY 和ORDER BY子句中.3.删除重复记录最高效的删除重复记录方法(因为使用了ROWID)Sql代码1.DELETE FROM EMP E WHERE E.ROWID >(SELECT MIN(X.ROWID)FROM EMP X WHERE X.EMP_NO = E.EMP_NO);DELETE FROM EMP E WHERE E.ROWID >(SELECT MIN(X.ROWID)FROM EMP X WHERE X.EMP_NO = E.EMP_NO);4.用TRUNCATE替代DELETE当删除表中的记录时,在通常情况下,回滚段(rollback segments)用来存放可以被恢复的信息,如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况),而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短.5.计算记录条数和一般的观点相反, count(*)比count(1)稍快,当然如果可以通过索引检索,对索引列的计数仍旧是最快的.例如 COUNT(EMPNO)6.用Where子句替换HAVING子句避免使用HAVING子句,HAVING 只会在检索出所有记录之后才对结果集进行过滤,这个处理需要排序、总计等操作,如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销, 例如: Sql代码1.--低效2.SELECT REGION,AVG(LOG_SIZE)FROM LOCATION GROUP BY REGION HAVING REGION REGION!= …SYDNEY‟AND REGION!= …PERTH‟3.--高效4.SELECT REGION,AVG(LOG_SIZE)FROMLOCATION WHERE REGION REGION!= …SYDNEY‟ ND REGION!= …PERTH‟ GROUP BYREGION--低效SELECT REGION,AVG(LOG_SIZE)FROM LOCATION GROUP BY REGION HAVING REGION REGION!= …SYDNEY‟AND REGION!= …PERTH‟--高效SELECT REGION,AVG(LOG_SIZE)FROMLOCATION WHERE REGION REGION!= …SYDNEY‟ ND REGION!= …PERTH‟ GROUP BY REGION7.用EXISTS替代IN在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率.Sql代码1.--低效2.SELECT * FROM EMP WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = …MELB‟)3.--高效:4.SELECT * FROM EMP WHERE EMPNO > 0 AND EXISTS(SELECT …X‟FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LO C = …MELB‟)--低效SELECT * FROM EMP WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = …MELB‟) --高效:SELECT * FROM EMP WHERE EMPNO > 0 AND EXISTS(SELECT …X‟FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = …MELB‟)8.用NOT EXISTS替代NOT IN在子查询中,NOT IN子句将执行一个内部的排序和合并.无论在哪种情况下,NOT IN都是最低效的(因为它对子查询中的表执行了一个全表遍历).为了避免使用NOT IN,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS.例如:SELECT …FROM EMPWHERE DEPT_NO NOT IN(SELECT DEPT_NO FROM DEPT WHERE DEPT_CAT=‟A‟);Sql代码1.--为了提高效率改写为:(方法一: 高效)SELECT ….FROM EMP A,DEPT B WHERE A.DEPT_NO = B.DEPT(+)AND B.DEPT_NO IS NULL AND B.DEPT_CAT(+)= …A‟2.--(方法二: 最高效)SELECT ….FROM EMP E WHERE NOT EXISTS(SELECT …X‟FROM DEPT D WHERE D.DEPT_NO = E.DEPT_NO AND DEPT_CAT = …A‟);3.--为了提高效率改写为:(方法一: 高效)SELECT ….FROM EMP A,DEPT B WHERE A.DEPT_NO =B.DEPT(+)AND B.DEPT_NO IS NULL AND B.DEPT_CAT(+)= …A‟4.--(方法二: 最高效)SELECT ….FROM EMP E WHERE NOT EXISTS(SELECT …X‟FROM DEPT D WHERE D.DEPT_NO = E.DEPT_NO AND DEPT_CAT = …A‟);9.用EXISTS替换DISTINCT当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT.一般可以考虑用EXIST替换例如: Sql代码1.--低效:2.SELECT DISTINCT DEPT_NO,DEPT_NAMEFROM DEPT D,EMP E WHERE D.DEPT_NO = E.DEPT_NO3.--高效:4.SELECT DEPT_NO,DEPT_NAMEFROM DEPT D WHERE EXISTS(SELECT …X‟FROM EMP E WHERE E.DEPT_NO =D.DEPT_NO);5.--EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果.--低效:SELECT DISTINCT DEPT_NO,DEPT_NAMEFROM DEPT D,EMP E WHERE D.DEPT_NO = E.DEPT_NO--高效:SELECT DEPT_NO,DEPT_NAMEFROM DEPT D WHERE EXISTS(SELECT …X‟FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);--EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果.10.用索引提高效率索引是表的一个概念部分,用来提高检索数据的效率,实际上ORACLE使用了一个复杂的自平衡B-tree结构,通常通过索引查询数据比全表扫描要快,当ORACLE找出执行查询和Update语句的最佳路径时,ORACLE优化器将使用索引,同样在联结多个表时使用索引也可以提高效率,另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证,除了那些LONG或LONG RAW数据类型, 你可以索引几乎所有的列.通常, 在大型表中使用索引特别有效.当然,你也会发现, 在扫描小表时,使用索引同样能提高效率,虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价.索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本身也会被修改,这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O,因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢注:定期的重构索引是有必要的.11.避免在索引列上使用计算WHERE子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描.举例:Sql代码1.--低效:2.SELECT …FROM DEPT WHERE SAL * 12 > 25000;3.--高效:4.SELECT … FROM DEPT WHERE SAL> 25000/12;--低效:SELECT …FROM DEPT WHERE SAL * 12 > 25000;--高效:SELECT … FROM DEPT WHERE SAL> 25000/12;12.用>=替代>Sql代码1.--如果DEPTNO上有一个索引2.--高效:SELECT *FROM EMPWHERE DEPTNO >=43.--低效:SELECT *FROM EMPWHERE DEPTNO >3--如果DEPTNO上有一个索引 4.--高效:SELECT *FROM EMPWHERE DEPTNO >=45.--低效:SELECT *FROM EMPWHERE DEPTNO >3两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录.第二篇:高效的SQL语句如何写高效率的SQL语句、Where子句中的连接顺序:ORACLE采用自下而上的顺序解析WHERE子句。
SQL执行效率分析
很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解。
比如:select * from table1 where name='zhangsan' and tID > 10000和执行:select * from table1 where tID > 10000 and name='zhangsan'一些人不知道以上两条语句的执行效率是否一样,因为如果简单的从语句先后上看,这两个语句的确是不一样,如果tID是一个聚合索引,那么后一句仅仅从表的10000条以后的记录中查找就行了;而前一句则要先从全表中查找看有几个name='zhangsan'的,而后再根据限制条件条件tID>10000来提出查询结果。
事实上,这样的担心是不必要的。
SQL SERVER中有一个“查询分析优化器”,它可以计算出where子句中的搜索条件并确定哪个索引能缩小表扫描的搜索空间,也就是说,它能实现自动优化。
虽然查询优化器可以根据where子句自动的进行查询优化,但大家仍然有必要了解一下“查询优化器”的工作原理,如非这样,有时查询优化器就会不按照您的本意进行快速查询。
在查询分析阶段,查询优化器查看查询的每个阶段并决定限制需要扫描的数据量是否有用。
如果一个阶段可以被用作一个扫描参数(SARG),那么就称之为可优化的,并且可以利用索引快速获得所需数据。
SARG的定义:用于限制搜索的一个操作,因为它通常是指一个特定的匹配,一个值得范围内的匹配或者两个以上条件的AND连接。
形式如下:列名操作符<常数或变量>或<常数或变量> 操作符列名列名可以出现在操作符的一边,而常数或变量出现在操作符的另一边。
如:Name=‟张三‟价格>50005000<价格Name=‟张三‟ and 价格>5000如果一个表达式不能满足SARG的形式,那它就无法限制搜索的范围了,也就是SQL SERVER必须对每一行都判断它是否满足WHERE子句中的所有条件。
SQL语句执行效率及分析
SQL语句执行效率及分析2.SQL提高查询效率2018-05-12 21:201.对查询进行优化,应尽量幸免全表扫描,第一应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量幸免在 where 子句中对字段进行 null 值判定,否则将导致引擎舍弃使用索引而进行全表扫描,如:select id from t where num is null能够在num上设置默认值0,确保表中num列没有null值,然后如此查询:select id from t where num=03.应尽量幸免在 where 子句中使用!=或<>操作符,否则将引擎舍弃使用索引而进行全表扫描。
4.应尽量幸免在 where 子句中使用 or 来连接条件,否则将导致引擎舍弃使用索引而进行全表扫描,如:select id from t where num=10 or num=20能够如此查询:select id from t where num=10union allselect id from t where num=205.in 和 not in 也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3)关于连续的数值,能用 between 就不要用 in 了:select id from t where num between 1 and 36.下面的查询也将导致全表扫描:select id from t where name like '%abc%'若要提高效率,能够考虑全文检索。
7.假如在 where 子句中使用参数,也会导致全表扫描。
因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问打算的选择推迟到运行时;它必须在编译时进行选择。
然而,假如在编译时建立访问打算,变量的值依旧未知的,因而无法作为索引选择的输入项。
如下面语句将进行全表扫描:select id from t where num=@num能够改为强制查询使用索引:select id from t with(index(索引名)) where num=@num8.应尽量幸免在 where 子句中对字段进行表达式操作,这将导致引擎舍弃使用索引而进行全表扫描。
项目中优化sql语句执行效率的方法
项目中优化sql语句执行效率的方法在项目开发中,优化SQL语句执行效率是非常重要的一项工作。
优化SQL语句可以提高数据库的性能,减少系统的响应时间,提高用户体验。
下面是一些优化SQL语句执行效率的方法:1. 使用索引索引是数据库中提高查询效率的重要手段。
在查询语句中使用索引可以大大提高查询速度。
在创建表时,可以根据表的特点和查询需求创建相应的索引。
在查询语句中,使用WHERE子句可以利用索引进行快速查询。
2. 避免使用SELECT *SELECT *会查询表中的所有列,包括不需要的列。
这样会增加查询的时间和资源消耗。
在查询语句中,只查询需要的列,可以减少查询时间和资源消耗。
3. 使用JOIN优化查询JOIN是连接两个或多个表的操作。
在使用JOIN时,应该尽量避免使用子查询,因为子查询会增加查询的时间和资源消耗。
可以使用JOIN 语句将多个表连接起来,减少查询时间和资源消耗。
4. 避免使用LIKELIKE是模糊查询,可以查询包含指定字符串的记录。
但是,LIKE查询会增加查询的时间和资源消耗。
在查询语句中,应该尽量避免使用LIKE,可以使用全文检索等方法代替。
5. 使用EXPLAIN分析查询语句EXPLAIN是MySQL中的一个命令,可以分析查询语句的执行计划。
通过分析执行计划,可以找到查询语句中的瓶颈,优化查询语句,提高查询效率。
6. 避免使用ORDER BYORDER BY是对查询结果进行排序的操作。
在查询语句中,应该尽量避免使用ORDER BY,因为排序会增加查询的时间和资源消耗。
如果需要排序,可以在查询语句中使用LIMIT子句限制查询结果的数量,减少排序的时间和资源消耗。
7. 使用缓存缓存是提高查询效率的重要手段。
在查询语句中,可以使用缓存来缓存查询结果,减少查询时间和资源消耗。
可以使用Memcached等缓存工具来实现缓存。
总之,优化SQL语句执行效率是提高数据库性能的重要手段。
在项目开发中,应该根据实际情况选择合适的优化方法,提高查询效率,提高用户体验。
SQL性能优化详解
SQL性能优化详解SQL是一种用于管理关系数据库的语言,对于大型数据库系统来说,SQL性能优化是至关重要的,因为它可以显著提高数据库查询和操作的效率。
本文将详细讨论SQL性能优化的几个关键方面。
1.优化查询语句查询语句是SQL性能优化的一个核心方面。
以下是几种优化查询语句的方法:-使用索引:索引是一种数据结构,可以大大加快查询操作。
在频繁的查询字段上创建索引,可以显著提高查询性能。
-减少查询行数:只查询需要的行数,可以减少查询的时间。
使用LIMIT关键字可以限制结果集的大小。
-避免使用SELECT*:只选择需要的字段,避免选择多余字段的开销。
-使用合适的JOIN:使用INNERJOIN、OUTERJOIN等合适的JOIN类型可以提高查询的效率。
2.优化数据库结构数据库结构的设计也会对SQL查询的性能产生影响。
以下是几种优化数据库结构的方法:-分解大表:将大表拆分为多个小表,可以减少查询的范围,提高查询的性能。
-正规化与反规范化:正规化是将数据库设计为多个表,以保持数据的一致性和完整性。
但是,对于查询频繁的场景,可以考虑使用反规范化来提高查询性能。
-使用合适的数据类型:选择合适的数据类型可以减少存储空间和提高查询效率。
例如,使用整型代替字符串型可以减少存储空间,并且比较整型比较字符串效率更高。
3.优化索引索引是提高查询性能的重要手段。
以下是几种优化索引的方法:-创建索引:在查询频繁的字段上创建索引,可以加速查询操作。
但是,创建过多的索引也会降低插入和更新的性能。
-使用复合索引:如果在多个字段上经常进行查询操作,可以创建复合索引,以减少索引的数量和提高查询性能。
-避免过长的索引名:过长的索引名可能导致索引占用较大的存储空间,降低性能。
4.缓存机制缓存机制可以减少查询频繁的数据的数据库访问次数,从而提高查询性能。
以下是几种缓存机制:-查询缓存:在数据库中缓存查询结果,下次查询相同的结果时,可以直接从缓存中获取,减少数据库的访问次数。
SQL语句执行原理及性能优化
图 1冬 季 工 况 下 迎 面 风 速 的 变 化 与 空 调 热 回 收 效 率 的 关 系 由上 图关 系 曲线可 以看 出 , 当转 轮 的厚 度 为 0 . 0 5米 曲线 。 时, 在转速小于 l 5时 , 全 热 回 收 和 显 热 回 收 的 回 收 效 率 随 着转 速 的不 断增 加 而 形 成 较快 的增 长 , 而在 转 速 大 于 1 5 时, 全 热 回收 和 显 热 回 收 的 回 收 效 率 随 着 转 速 的 增 加 趋 势 空 调 比较 缓 慢 , 而且全 热 回收 和显 热 回收 的 热 回收 效率 呈现 出 热 l 川 了基 本 相 同 的 变 化 趋 势 。
程 序 因 处 理 的 数 据 量 过 大而 造 成 机 器死 机 的情 况 时 有 发 生 。 因 此 , 如何 有 效地提 高 S QL语 句 的 执 行 效 率 , 优化 S QL语 句 的性 能, 越 来越 成 为 开 发 人 员 关 心 的 重要 课 题 。
关键 词 : S QL; 执 行原理 ; 性 能优 化 中图分类号 : TB 文献 标 识 码 : A 文章编 号 : 1 6 7 2 — 3 1 9 8 ( 2 0 1 3 ) 0 5 — 0 1 8 6 . 0 2
收 效
璋£
( %)
3 结 语
随 着 目前 全 世 界 范 围 内 的 能 源 形 势 的 不 断 紧 张 , 进 行 空 调 系 统 热 回收 的 开 发 和 研 究 以 及 空 调 热 回 收 技 术 的 应 用 研 究 是 非 常 的有 必 要 的 , 其本 质是 废气 的利 用 , 这 是 进 行 建 筑物 节能的重要 手段 和有 效措 施 , 对 于 我 国 能 源 供 应 压 力 的减 小 以 及 能 源 的 充 分 利 用 和 节 约 具 有 重 要 意 义 。 本 文 首 先 对 于 空 调 热 回 收 系 统 以 及 空 调 系 统 的 热 回 收 节 能 做 了 详 细 的 阐述 , 在此基础上 , 着 重 讨 论 了 空 调 热 回 收 系 统 节 能 中 热 回 收 效 率 的影 响 因 素 , 主 要 包 括 空 调 回 风 量 和 风 管 漏 风 对 热 回收 效 率 的 影 响 、 建 筑 物 维 护 结 构 的 密 封 性 对 热 回 收 效 率 的影 响 以 及 空 调 热 回 收装 置 本 身 对 空 调 热 回 收 的影 响 三个方 面, 通过对这些 因素的分 析研 究 , 有 助 于 在 提 高 空 调 系统热 回收效率 的同 时, 实 现 空 调 热 回 收 系 统 的 科 学 合 理 配置 , 对于实际工程 中空调热 回收装 置 的选用 、 空 调 热 回 收 效 果 的完 善 具 有 重 要 意 义 。
提高SQL效率共14页word资料
sql语句看似简单,其实大有学问。
相同的结果,不同程序员写的语句速度可能差距很大。
下面的内容对优化速度大有用处:(1)整合简单,无关联的数据库访问:如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)(2)删除重复记录:最高效的删除重复记录方法 ( 因为使用了ROWID)例子:DELETE FROM EMP E WHERE E.ROWID > (SELECTMIN(X.ROWID)FROM EMP X WHERE X.EMP_NO = E.EMP_NO);(3)用TRUNCATE替代DELETE:当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况) 而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短. (译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)(4)选择最有效率的表名顺序(只在基于规则的优化器中有效):ORACLE 的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。
如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.(5)WHERE子句中的连接顺序.:ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.(6)SELECT子句中避免使用‘ * ‘:ORACLE在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间(7)减少访问数据库的次数:ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等;(8)在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200(9)使用DECODE函数来减少处理时间:使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.(11)用Where子句替换HAVING子句:避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销. (非oracle中)on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后,因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,where也应该比having快点的,因为它过滤数据后才进行sum,在两个表联接时才用on的,所以在一个表的时候,就剩下where跟having比较了。
NC SQL规范及效率优化知识分享
Yonyou Software Corporation
SQL 规范——高效SQL
使用表的别名
例: 下面两个Sql执行效果哪个更好?(字段a,b,c是表table1的字段,x,y 是table2的字段) #SQL一 Select a,b,x from table1,table2 where a>100 and c=y #SQL二 Select t1.a,t1.b,t2.x from table1 t1,table2 t2 where t1.a>100 and t1.c = t2.y 使用表的别名(Alias),当在SQL语句中连接多个表时,请使用表的别 名并把别名前缀于每个Column上,这样可以 1)减少解析的时间 2)减少那些由Column歧义引起的语法错误
2 3
1
Yonyou Software Corporation
SQL规范
Yonyou Software Corporation
SQL 规范——书写风格
SQL语句全部使用小写(目前NC的整体习惯); 引用字符时用单引号。如:update testable set idcol=’abcd’。 连接符或运算符or、in、and、=、<=、>=,+,- 等前后加上一个空格; 在子查询中前后必须加上括号, select col1, col2 from tablea where col3 in ( select col4 from tableb where col4>0); 当SQL语句含有运算符时,运算符需与其他字符串用空格区分(或者用
1、select * from t where id=7369;
2、select * from t where id='7369';
Oracle的SQL语句执行效率问题查找与解决方法
Oracle的SQL语句执行效率问题查找与解决方法一、识别占用资源较多的语句的方法(4种方法)1.测试组和最终用户反馈的与反应缓慢有关的问题。
2.利用V$SQLAREA视图提供了执行的细节。
(执行、读取磁盘和读取缓冲区的次数)•数据列EXECUTIONS:执行次数DISK_READS:读盘次数COMMAND_TYPE:命令类型(3:select,2:insert;6:update;7delete;47:pl/sql程序单元)OPTIMIZER_MODE:优化方式SQL_TEXT:Sql语句SHARABLE_MEM:占用shared pool的内存多少BUFFER_GETS:读取缓冲区的次数•用途1、帮忙找出性能较差的SQL语句2、帮忙找出最高频率的SQL3、帮忙分析是否需要索引或改善联接3.监控当前Oracle的session,如出现时钟的标志,表示此进程中的sql运行时间较长。
4.Trace工具:a)查看数据库服务的初始参数:timed_statistics、user_dump_dest和max_dump_file_sizeb)Step 1: alter session set sql_trace=truec)Step 2: run sql;d)Step 3: alter session set sql_trace=falsee)Step 4:使用“TKPROF”转换跟踪文件f)Parse,解析数量大通常表明需要增加数据库服务器的共享池大小,query或current提取数量大表明如果没有索引,语句可能会运行得更有效,disk提取数量表明索引有可能改进性能,library cache中多于一次的错过表明需要一个更大的共享池大小二、如何管理语句处理和选项•基于成本(Cost Based)和基于规则(Rule Based)两种优化器,简称为CBO 和RBO •Optimizer Mode参数值:Choose:如果存在访问过的任何表的统计数据,则使用基于成本的Optimizer,目标是获得最优的通过量。
分析SQL执行效率(一)
分析SQL执⾏效率(⼀)定位慢 SQL定位慢 SQL 的两种⽅案查看慢查询⽇志确定已经执⾏完的慢查询show processlist 查看正在执⾏的慢查询通过慢查询⽇志MySQL 的慢查询⽇志⽤来记录在 MySQL 中响应时间超过参数 long_query_time(单位秒,默认值 10)设置的值并且扫描记录数不⼩于 min_examined_row_limit(默认值 0)的语句使⽤慢查询⽇志,⼀般分为四步:开启慢查询⽇志、设置慢查询阀值、确定慢查询⽇志路径、确定慢查询⽇志的⽂件名。
⾸先开启慢查询⽇志,由参数 slow_query_log 决定是否开启,默认环境下,慢查询⽇志是关闭的mysql> set global slow_query_log = on;Query OK, 0 rows affected (0.00 sec)设置慢查询时间阀值mysql> set global long_query_time = 1;Query OK, 0 rows affected (0.00 sec)慢查询⽇志的路径默认是 MySQL 的数据⽬录mysql> show global variables like "datadir";+---------------+-------------+| Variable_name | Value |+---------------+-------------+| datadir | /data/3306/ |+---------------+-------------+1 row in set (0.00 sec)确定慢查询⽇志的⽂件名mysql> show global variables like "slow_query_log_file";+---------------------+------------------------------+| Variable_name | Value |+---------------------+------------------------------+| slow_query_log_file | /data/3306/mysql_01-slow.log |+---------------------+------------------------------+1 row in set (0.01 sec)根据上⾯的查询结果,可以直接查看 /data/3306/mysql_01-slow.log ⽂件获取已经执⾏完的慢查询[root@mysql_01 ~]# tail -n5 /data/3306/mysql_01-slow.log# Time: 2020-06-17T03:47:28.224746Z# User@Host: root[root] @ localhost [] Id: 5# Query_time: 10.003112 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0SET timestamp=1592365648;select sleep(10);[root@mysql_01 ~]#tail -n5 :只查看慢查询⽂件的最后 5 ⾏Time:慢查询发⽣的时间User@Host:客户端⽤户和 IPQuery_time:查询时间Lock_time:等待表锁的时间Rows_sent:语句返回的⾏数Rows_examined:语句执⾏期间从存储引擎读取的⾏数通过 show processlist有时慢查询正在执⾏,已经导致数据库负载偏⾼了,⽽由于慢查询还没执⾏完,因此慢查询⽇志还看不到任何语句。
关于SQL语句执行效率的研究
关于SQL语句执行效率的研究关于SQL语句执行效率的研究摘要在针对数据库操作的应用程序设计中,SQL语句的编写也会影响到程序响应速度和用户的体验度,尤其是数据量较大的应用。
本文通过对SQL语句的执行顺序进行分析,探讨和分析提高SQL语句效率的方法以及SQL语句的优化方式。
【关键词】SQL语句执行效率方法随着计算机技术的开展,各种各样的应用软件进入到我们的生活中。
大多数软件在与用户交互时都会进行数据的查询、存储等操作。
科学合理的数据库查询语句可以提高数据库的查询性能,随之将会提高软件的响应速度和用户体验度,在数据库应用系统中起着关键的作用。
1 SQL语句SQL语句是STRUCTURED QUERY LAN -GUAGE的缩写,即结构化查询语言。
在1986年10月通过了美国国家标准局的数据库语言美国标准,经过多年的扩展和标准化,在各种不同的数据库中已经根本到达通用。
可以独立于数据库和计算机软硬件。
我们这里讨论的是结构化查询语言的一局部,叫做数据查询语句。
数据查询语句也称为数据检索语句,用以从数据库表中获得需要的数据,返回给应用程序。
数据查询语句中最常用的保存字是SELECT,其他的还有WHERE,ORDER BY,GROUP BY和HAVING。
这些DQL保存字与其他类型的SQL语句一起使用。
比方:SELECT id,name,age,address FROM students WHERE name=’rose’ ORDER BY age这条查询语句的意思是:从students学生表中查询出所有名叫rose的的学生,并且返回的结果集按照age年龄字段顺序排列。
2 SQL语句的效率SQL作为查询语言有灵活的编写方式,语句的写法完全取决于编写者。
当数据库收到一个查询语句时,首先完成语法解释,然后再进行编译,生成可以执行的“执行方案〞。
在语句编译过程中,数据库会根据指令内容和估算可能的执行方案,再根据每个方案的运行本钱选择一个数据库认为本钱最低的方案执行。
SQL语句的执行顺序和效率
SQL语句的执⾏顺序和效率今天上午在开发的过程中,突然遇到⼀个问题,需要了解SQL语句的执⾏顺序才能继续,上⽹上查了⼀下相关的资料,现整理如下:⼀、sql语句的执⾏步骤:1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。
2)语义分析,检查语句中涉及的所有数据库对象是否存在,且⽤户有相应的权限。
3)视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。
4)表达式转换,将复杂的 SQL 表达式转换为较简单的等效连接表达式。
5)选择优化器,不同的优化器⼀般产⽣不同的“执⾏计划”6)选择连接⽅式, ORACLE 有三种连接⽅式,对多表连接 ORACLE 可选择适当的连接⽅式。
7)选择连接顺序,对多表连接 ORACLE 选择哪⼀对表先连接,选择这两表中哪个表做为源数据表。
8)选择数据的搜索路径,根据以上条件选择合适的数据搜索路径,如是选⽤全表搜索还是利⽤索引或是其他的⽅式。
9)运⾏“执⾏计划”⼆、oracle 共享原理:ORACLE将执⾏过的SQL语句存放在内存的共享池(shared buffer pool)中,可以被所有的数据库⽤户共享当你执⾏⼀个SQL语句(有时被称为⼀个游标)时,如果它和之前的执⾏过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的执⾏路径. 这个功能⼤⼤地提⾼了SQL的执⾏性能并节省了内存的使⽤三、oracle 语句提⾼查询效率的⽅法:1: where column in(select * from ... where ...); 2:... where exists (select 'X' from ...where ...); 第⼆种格式要远⽐第⼀种格式的效率⾼。
在Oracle中可以⼏乎将所有的IN操作符⼦查询改写为使⽤EXISTS的⼦查询使⽤EXIST,Oracle系统会⾸先检查主查询,然后运⾏⼦查询直到它找到第⼀个匹配项,这就节省了时间 Oracle系统在执⾏IN⼦查询时,⾸先执⾏⼦查询,并将获得的结果列表存放在在⼀个加了索引的临时表中避免使⽤having字句避免使⽤HAVING⼦句, HAVING 只会在检索出所有记录之后才对结果集进⾏过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE⼦句限制记录的数⽬,那就能减少这⽅⾯的开销SQL Select语句完整的执⾏顺序:1、from⼦句组装来⾃不同数据源的数据;2、where⼦句基于指定的条件对记录⾏进⾏筛选;3、group by⼦句将数据划分为多个分组;4、使⽤聚集函数进⾏计算;5、使⽤having⼦句筛选分组;6、计算所有的表达式;7、使⽤order by对结果集进⾏排序。
SQL语句效率
SQL语句效率1. SQL优化的原则是:将一次操作需要读取的BLOCK数减到最低,即在最短的时间达到最大的数据吞吐量。
调整不良SQL通常可以从以下几点切入:? 检查不良的SQL,考虑其写法是否还有可优化内容? 检查子查询考虑SQL子查询是否可以用简单连接的方式进行重新书写? 检查优化索引的使用? 考虑数据库的优化器2. 避免出现SELECT * FROM table 语句,要明确查出的字段。
3. 在一个SQL语句中,如果一个where条件过滤的数据库记录越多,定位越准确,则该where条件越应该前移。
4. 查询时尽可能使用索引覆盖。
即对SELECT的字段建立复合索引,这样查询时只进行索引扫描,不读取数据块。
5. 在判断有无符合条件的记录时建议不要用SELECT COUNT (*)和select top 1 语句。
6. 使用内层限定原则,在拼写SQL语句时,将查询条件分解、分类,并尽量在SQL语句的最里层进行限定,以减少数据的处理量。
7. 应绝对避免在order by子句中使用表达式。
8. 如果需要从关联表读数据,关联的表一般不要超过7个。
9. 小心使用IN 和OR,需要注意In集合中的数据量。
建议集合中的数据不超过200个。
10. <> 用< 、> 代替,>用>=代替,<用<=代替,这样可以有效的利用索引。
11. 在查询时尽量减少对多余数据的读取包括多余的列与多余的行。
12. 对于复合索引要注意,例如在建立复合索引时列的顺序是F1,F2,F3,则在where或order by子句中这些字段出现的顺序要与建立索引时的字段顺序一致,且必须包含第一列。
只能是F1或F1,F2或F1,F2,F3。
否则不会用到该索引。
13. 多表关联查询时,写法必须遵循以下原则,这样做有利于建立索引,提高查询效率。
格式如下select sum (table1.je)from table1 table1, table2 table2, table3 table3 where (table1的等值条件(=)) and (table1的非等值条件) and (table2与table1的关联条件) and (table2的等值条件) and (table2的非等值条件) and (table3与table2的关联条件) and (table3的等值条件) and (table3的非等值条件)。
SQL语言的查询效率
如何提高SQL语言的查询效率由于SQL是面向结果而不是面向过程的查询语言,所以一般支持SQL语言的大型关系型数据库都使用一个基于查询成本的优化器,为即时查询提供一个最佳的执行策略。
对于优化器,输入是一条查询语句,输出是一个执行策略。
一条SQL查询语句可以有多种执行策略,优化器将估计出全部执行方法中所需时间最少的所谓成本最低的那一种方法。
所有优化都是基于用记所使用的查询语句中的where子句,优化器对where子句中的优化主要用搜索参数(Serach Argument)。
搜索参数的核心思想就是数据库使用表中字段的索引来查询数据,而不必直接查询记录中的数据。
带有 =、<、<=、>、>= 等操作符的条件语句可以直接使用索引,如下列是搜索参数:emp_id = "10001" 或 salary > 3000 或 a =1 and c = 7而下列则不是搜索参数:salary = emp_salary 或 dep_id != 10 或 salary * 12 >= 3000 或 a=1 or c=7应当尽可能提供一些冗余的搜索参数,使优化器有更多的选择余地。
请看以下3种方法:第一种方法:select employee.emp_name,department.dep_name from department,employee where (employee.dep_id = department.dep_id) and (department.dep_code='01') and (employee.dep_code='01');它的搜索分析结果如下:Estimate 2 I/O operationsScan department using primary keyfor rows where dep_code equals '01'Estimate getting here 1 timesScan employee sequentiallyEstimate getting here 5 times第二种方法:select employee.emp_name,department.dep_name from department,employee where (employee.dep_id = department.dep_id) and (department.dep_code='01');它的搜索分析结果如下:Estimate 2 I/O operationsScan department using primary keyfor rows where dep_code equals '01'Estimate getting here 1 timesScan employee sequentiallyEstimate getting here 5 times第一种方法与第二种运行效率相同,但第一种方法最好,因为它为优化器提供了更多的选择机会。
SQL语句的执行原理分析及where查询条件决定SQL效率
SQL语句的执行原理分析及where查询条件决定SQL效率SQL语句的执行原理分析及where 查询条件决定SQL效率原理:第一步:应用程序把查询SQL语句发给服务器端执行。
我们在数据层执行SQL语句时,应用程序会连接到相应的数据库服务器,把SQL语句发送给服务器处理。
第二步:服务器解析请求的SQL语句。
1:SQL计划缓存,经常用查询分析器的朋友大概都知道这样一个事实,往往一个查询语句在第一次运行的时候需要执行特别长的时间,但是如果你马上或者在一定时间内运行同样的语句,会在很短的时间内返回查询结果。
原因:1):服务器在接收到查询请求后,并不会马上去数据库查询,而是在数据库中的计划缓存中找是否有相对应的执行计划,如果存在,就直接调用已经编译好的执行计划,节省了执行计划的编译时间。
2):如果所查询的行已经存在于数据缓冲存储区中,就不用查询物理文件了,而是从缓存中取数据,这样从内存中取数据就会比从硬盘上读取数据快很多,提高了查询效率.数据缓冲存储区会在后面提到。
2:如果在SQL计划缓存中没有对应的执行计划,服务器首先会对用户请求的SQL语句进行语法效验,如果有语法错误,服务器会结束查询操作,并用返回相应的错误信息给调用它的应用程序。
注意:此时返回的错误信息中,只会包含基本的语法错误信息,例如select 写成selec等,错误信息中如果包含一列表中本没有的列,此时服务器是不会检查出来的,因为只是语法验证,语义是否正确放在下一步进行。
3:语法符合后,就开始验证它的语义是否正确,例如,表名,列名,存储过程等等数据库对象是否真正存在,如果发现有不存在的,就会报错给应用程序,同时结束查询。
4:接下来就是获得对象的解析锁,我们在查询一个表时,首先服务器会对这个对象加锁,这是为了保证数据的统一性,如果不加锁,此时有数据插入,但因为没有加锁的原因,查询已经将这条记录读入,而有的插入会因为事务的失败会回滚,就会形成脏读的现象。
SQL的执行效率
SQL的执行效率ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.例如:A表2万条记录,B表1条记录选择B作为基础表(最好的方法)select count(*) from a ,b执行时间0.96秒选择TAB2作为基础表(不佳的方法)select count(*) from b,a 执行时间26.09秒SELECT子句中避免使用‘ * ‘当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用‘*’ 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.<> 操作符(不等于)不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。
推荐方案:用其它相同功能的操作运算代替,如a<>0 改为a>0 or a<0a<>’’ 改为a>’’WHERE子句中的连接顺序.ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾. 例如:(低效,执行时间156.3秒)se lect * from emp e where sal > 50000 and job = ‘manager’and 25 < (select count(*) from emp where mgr=e.empno);(高效,执行时间10.6秒)select * from emp e where 25 < (select count(*) from emp where mgr=e.empno)and sal > 50000 and job = ‘manager’;LIKE操作符LIKE操作符可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好则会产生性能上的问题,如LIKE ‘%5400%’ 这种查询不会引用索引,而LIKE ‘X5400%’则会引用范围索引。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SQL语句执行效率及分析(note)1.关于SQL查询效率,100w数据,查询只要1秒,与您分享:机器情况p4: 2.4内存: 1 Gos: windows 2003数据库: ms sql server 2000目的: 查询性能测试,比较两种查询的性能SQL查询效率step by step-- setp 1.-- 建表create table t_userinfo(userid int identity(1,1) primary key nonclustered,nick varchar(50) not null default '',classid int not null default 0,writetime datetime not null default getdate())go-- 建索引create clustered index ix_userinfo_classid on t_userinfo(classid)go-- step 2.declare @i intdeclare @k intdeclare @nick varchar(10)set @i = 1while @i<1000000beginset @k = @i % 10set @nick = convert(varchar,@i)insert into t_userinfo(nick,classid,writetime) values(@nick,@k,getdate()) set @i = @i + 1end-- 耗时08:27 ,需要耐心等待-- step 3.select top 20 userid,nick,classid,writetime from t_userinfo where userid not in(select top 900000 userid from t_userinfo order by userid asc )-- 耗时8 秒,够长的-- step 4.select erid,b.nick,b.classid,b.writetime from(select top 20 erid from(select top 900020 userid from t_userinfo order by userid asc ) a order by erid desc) a inner join t_userinfo b on erid = eridorder by erid asc-- 耗时1 秒,太快了吧,不可以思议-- step 5 where 查询select top 20 userid,nick,classid,writetime from t_userinfo where classid = 1 and userid not in(select top 90000 userid from t_userinfowhere classid = 1order by userid asc)-- 耗时2 秒-- step 6 where 查询select erid,b.nick,b.classid,b.writetime from(select top 20 erid from(select top 90000 userid from t_userinfowhere classid = 1order by userid asc) a order by erid desc) a inner join t_userinfo b on erid = eridorder by erid asc-- 查询分析器显示不到1 秒.查询效率分析:子查询为确保消除重复值,必须为外部查询的每个结果都处理嵌套查询。
在这种情况下可以考虑用联接查询来取代。
如果要用子查询,那就用EXISTS替代IN、用NOT EXISTS替代NOT IN。
因为EXISTS引入的子查询只是测试是否存在符合子查询中指定条件的行,效率较高。
无论在哪种情况下,NOT IN都是最低效的。
因为它对子查询中的表执行了一个全表遍历。
建立合理的索引,避免扫描多余数据,避免表扫描!几百万条数据,照样几十毫秒完成查询.2.SQL提高查询效率2008-05-12 21:201.对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引。
2.应尽量避免在where 子句中对字段进行null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=03.应尽量避免在where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
4.应尽量避免在where 子句中使用or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num=10 or num=20可以这样查询:select id from t where num=10union allselect id from t where num=205.in 和not in 也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3)对于连续的数值,能用between 就不要用in 了:select id from t where num between 1 and 36.下面的查询也将导致全表扫描:select id from t where name like '%abc%'若要提高效率,可以考虑全文检索。
7.如果在where 子句中使用参数,也会导致全表扫描。
因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。
然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。
如下面语句将进行全表扫描:select id from t where num=@num可以改为强制查询使用索引:select id from t with(index(索引名)) where num=@num8.应尽量避免在where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。
如:select id from t where num/2=100应改为:select id from t where num=100*29.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。
如:select id from t where substring(name,1,3)='abc'--name以abc开头的idselect 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'10.不要在where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
12.不要写一些没有意义的查询,如需要生成一个空表结构:select col1,col2 into #t from t where 1=0这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:create table #t(...)13.很多时候用exists 代替in 是一个好的选择:select num from a where num in(select num from b)用下面的语句替换:select num from a where exists(select 1 from b where num=a.num)14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
15.索引并不是越多越好,索引固然可以提高相应的select 的效率,但同时也降低了insert 及update 的效率,因为insert 或update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。
一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
16.应尽可能的避免更新clustered 索引数据列,因为clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。
若应用系统需要频繁更新clustered 索引数据列,那么需要考虑是否应将该索引建为clustered 索引。
17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。
这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
18.尽可能的使用varchar/nvarchar 代替char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
19.任何地方都不要使用select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
20.尽量使用表变量来代替临时表。
如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。
21.避免频繁创建和删除临时表,以减少系统表资源的消耗。
22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。
但是,对于一次性事件,最好使用导出表。
23.在新建临时表时,如果一次性插入数据量很大,那么可以使用select into 代替create table,避免造成大量log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。