SQL语句优化

在程序开发中怎样写SQL语句可以提高数据库的性能

1、首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个10万条记录的表中查1条记录,那查询优化器会选 择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用“全表扫描”方式。 可见,执行计划并不是固定的,它是“个性化的”。产生一个正确 的“执行计划”有两点很重要: (1) SQL语句是否清晰地告诉查询优化器它想干什么? (2) 查询优化器得到的数据库统计信息是否是最新的、正确的? 2、统一SQL语句的写法 对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的。 select * from dual Select * From dual 其实就是大小写不同,查询分析器就认为是两句不同的SQL语句,必须进行两次解析。生成2个执行计划。所以作为程序员,应该保证相同的查询语句在任何地方都一致,多一个空格都不行! 3、不要把SQL语句写得太复杂 我经常看到,从数据库中捕捉到的一条SQL语句打印出来有2张A4纸这么长。一般来说这么复杂的语句通常都是有问题的。我拿着这2页长的SQL语句去请教原作者,结果他说时间太长,他一时也看不懂了。可想而知,连原作者都有可能看糊涂的SQL语句,数据库也一样会看糊涂。 一般,将一个Select语句的结果作为子集,然后从该子集中再进行查询,这种一层嵌套语句还是比较常见的,但是根据经验,超过3层嵌套,查询优化器就很容易给出错误的执行计划。因为它被绕晕了。像这种类似人工智能的东西,终究比人的分辨力要差些,如果人都看晕了,我可以保证数据库也会晕的。 另外,执行计划是可以被重用的,越简单的SQL语句被重用的可能性越高。而复杂的SQL语句只要有一个字符发生变化就必须重新解析,

sql语句(mysql优化)绝对经典

sql语句(mysql优化)绝对经典 误区1:count(1)和count(primary_key) 优于count(*) 很多人为了统计记录条数,就使用count(1) 和count(primary_key) 而不是count(*) ,他们认为这样性能更好,其实这是一个误区。对于有些场景,这样做可能性能会更差,应为数据库对count(*) 计数操作做了一些特别的优化。 误区2:count(column) 和count(*) 是一样的 这个误区甚至在很多的资深工程师或者是DBA 中都普遍存在,很多人都会认为这是理所当然的。实际上,count(column) 和count(*) 是一个完全不一样的操作,所代表的意义也完全不一样。count(column) 是表示结果集中有多少个column字段不为空的记录,count(*) 是表示整个结果集有多少条记录 误区3:select a,b from … 比select a,b,c from …可以让数据库访问更少的数据量 这个误区主要存在于大量的开发人员中,主要原因是对数据库的存储原理不是太了解。实际上,大多数关系型数据库都是按照行(row)的方式存储,而数据存取操作都是以一个固定大小的IO单元(被称作block 或者page)为单位,一般为4KB,8KB… 大多数时候,每个IO单元中存储了多行,每行都是存储了该行的所有字段(lob等特殊类型字段除外)。 所以,我们是取一个字段还是多个字段,实际上数据库在表中需要访问的数据量其实是一样的。当然,也有例外情况,那就是我们的这个查询在索引中就可以完成,也就是说当只取a,b两个字段的时候,不需要回表,而c这个字段不在使用的索引中,需要回表取得其数据。在这样的情况下,二者的IO量会有较大差异。(覆盖索引) 误区4:order by 一定需要排序操作 我们知道索引数据实际上是有序的,如果我们的需要的数据和某个索引的顺序一致,而且我们的查询又通过这个索引来执行,那么数据库一般会省略排序操作,而直接将数据返回,因为数据库知道数据已经满足我们的排序需求了。实际上,利用索引来优化有排序需求的SQL,是一个非常重要的优化手段。延伸阅读:MySQL ORDER BY 的实现分析,MySQL 中GROUP BY 基本实现原理以及MySQL DISTINCT 的基本实现原理。(order by null)

如何优化sql语句

如何优化sql语句.txt心态决定状态,心胸决定格局,眼界决定境界。当你的眼泪忍不住要流出来的时候,睁大眼睛,千万别眨眼,你会看到世界由清晰到模糊的全过程。2010-01-18 honglove (高级程序员) 1、查询时不返回不需要的行、列 业务代码要根据实际情况尽量减少对表的访问行数,最小化结果集,在查询时,不要过多地使用通配符如:select * from table1语句,要用到几列就选择几列,如:select col1,col2 from table1;在可能的情况下尽量限制结果集行数如:select top 100 col1,col2,col3 from talbe2,因为某些情况下用户是不需要那么多的数据的。 2、合理使用EXISTS, NOT EXISTS字句 如下所示: SELECT SUM(T1.C1) FROM T1 WHERE ((SELECT COUNT(*) FROM T2 WHERE T2.C2=T1.C2)>0) SELECT SUM(T1.C1) FROM T1 WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2=T1.C2) 两种产生相同的结果,但是后者的效率显然要高过于前者。银行后者不会产生大量锁定的表扫描或是索引扫描。 经常需要些一个T_SQLL语句比较一个父结果集和子结果集,从而找到是否存在在父结果集中有而在子结果集中乜嘢的记录,如: SELECT _a.hdr_key FROM hdr_tb1 a -----------tb1 a 表示tb1用别名a代替 WHERE NOT EXISTS (SELECT * FROM dt1_tb1 b WHERE a.hdr_key = b.hdr_key) SELECT _a.hdr_key FROM hdr_tb1 a -----------tb1 a 表示tb1用别名a代替 LEFT JION dt1_tb1 b ON a.hdr_key = b.hdr_key WHERE b.hdr_key IS NULL SELECT hdr_key FROM hdr_tb1

2020年(Oracle管理)如何优化SQL语句以提高Oracle执行效率

(Oracle管理)如何优化SQL语句以提高Oracle执 行效率

(1)选择最有效率的表名顺序(只在基于规则的优化器中有效): Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表drivingtable)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询,那就需要选择交叉表(intersectiontable)作为基础表,交叉表是指那个被其他表所引用的表。 (2)WHERE子句中的连接顺序: Oracle采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。(3)SELECT子句中避免使用‘*’: Oracle在解析的过程中,会将‘*’依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间。 (4)减少访问数据库的次数: Oracle在内部执行了许多工作:解析SQL语句,估算索引的利用率,绑定变量,读数据块等。(5)在SQL*Plus,SQL*Forms和Pro*C中重新设置ARRAYSIZE参数,可以增加每次数据库访问的检索数据量,建议值为200。 (6)使用DECODE函数来减少处理时间: 使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。 (7)整合简单,无关联的数据库访问: 如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)。 (8)删除重复记录: 最高效的删除重复记录方法(因为使用了ROWID)例子:DELETEFROMEMPEWHEREE.ROWID>(SELECTMIN(X.ROWID)

基础:如何编写优化的sql语句

一.SQL的优化器执行分析 在ORACLE RDBMS SERVER软件的内部,对于SQL语句的执行有一个优化器(OPTIMIZER)对SQL语句的执行进行优化。在我们使用后面介绍的工具对SQL的执行路径进行查看的时候,系统显示出来的是由优化器给出的执行路径的解释方案,如果对优化器的解释方案不了解的话,就无法针对出现的问题进行SQL语句的调整。现把ORACLE8提供的优化器的执行解释方案公布如下。 这部分内容的详细解释可以参照oracle的文档。这里给出的是快速参考。实际上,这些操作的含义往往名字上就可以表现出来,不用查手册。 1.如何看SQL解释方案 Execution Plan ---------------------------------------------------------- 1SELECT STATEMENT Optimizer=CHOOSE (Cost=94 Card=1) 2SORT (AGGREGATE) 3COUNT (STOPKEY) 4INDEX (FULL SCAN) OF 'PK_TBI_TM' (UNIQUE) (Cost=94 Car d=27164) (图1) 图1为ORACLE对语句“select count(*) from tbi_tm where rownum<10”给出的一个执行的解释方案,那我们该如何看这个方案呢?我们在看这个执行方案的时候要遵循一个原则“由里到外,由高到低”,同时“由里到外”不能违反“由高到低”的原则。因此上述的语句的执行步骤顺序为:4、3、2;假设存在一个步骤5的话,而且它的层次同3一致,那么,上述语句的执行步骤顺序就会改为:4、3、5、2。在图1中还给出了执行了何种操作(例如:INDEX(FULL SCAN),COUNT (STOPKEY)等,具体的说明在下面进行解释),同时在最后还给出了执

SQL Server优化之SQL语句优化

一切都是为了性能,一切都是为了业务 (2) 二、执行顺序 (3) 三、只返回需要的数据 (4) 四、尽量少做重复的工作 (5) 五、注意临时表和表变量的用 (6) 六、子查询的用法 (7) 七:尽量使用索引 (10) 八:多表连接的连接条件对索引的选择有着重要的意义,所以我们在写连接条件条件的时候需要特别注意。 (15)

一切都是为了性能,一切都是为了业务 一、查询的逻辑执行顺序 (1) FROM left_table (3) join_type JOIN right_table (2) ON join_condition (4) WHERE where_condition (5) GROUP BY group_by_list (6) WITH {cube | rollup} (7) HAVING having_condition (8) SELECT (9) DISTINCT (11) top_specification select_list (9) ORDER BY order_by_list 标准的SQL 的解析顺序为: (1) FROM 子句组装来自不同数据源的数据 (2) WHERE 子句基于指定的条件对记录进行筛选 (3) GROUP BY 子句将数据划分为多个分组 (4) 使用聚合函数进行计算 (5) 使用HAVING子句筛选分组

(6) 计算所有的表达式 (7) 使用ORDER BY对结果集进行排序 二、执行顺序 1. FROM:对FROM子句中前两个表执行笛卡尔积生成虚拟表vt1 2. ON: 对vt1表应用ON筛选器只有满足join_condition 为真的行才被插入vt2 3. OUTER(join):如果指定了OUTER JOIN保留表(preserved table)中未找到的行将行作为外部行添加到vt2,生成t3,如果from包含两个以上表,则对上一个联结生成的结果表和下一个表重复执行步骤和步骤直接结束。 4. WHERE:对vt3应用WHERE 筛选器只有使where_condition 为true的行才被插入vt4 5. GROUP BY:按GROUP BY子句中的列列表对vt4中的行分组生成vt5 6. CUBE|ROLLUP:把超组(supergroups)插入vt6,生成vt6 7. HAVING:对vt6应用HAVING筛选器只有使having_condition 为true的组才插入vt7 8. SELECT:处理select列表产生vt8 9. DISTINCT:将重复的行从vt8中去除产生vt9 10. ORDER BY:将vt9的行按order by子句中的列列表排序生成一个游标vc10

优化 SQL SELECT 语句性能的 6 个简单技巧

SELECT语句的性能调优有时是一个非常耗时的任务,在我看来它遵循帕累托原则。20%的努力很可能会给你带来80%的性能提升,而为了获得另外20%的性能提升你可能需要花费80%的时间。除非你在金星工作,那里的每一天都等于地球上的243天,否则交付期限很有可能使你没有足够的时间来调优SQL查询。 根据我多年编写和运行SQL语句的经验,我开始开发一个检查列表,当我试图提高查询性能时供我参考。在进行查询计划和阅读我使用的数据库文档之前,我会参考其中的内容,数据库文档有时会很复杂。我的检查列表绝对说不上全面或科学,它更像是一个保守计算,但我可以说,遵循这些简单的步骤大部分时间我确实能得到性能提升。检查列表如下。 检查索引 在SQL语句的WHERE和JOIN部分中用到的所有字段上,都应该加上索引。进行这个3分钟SQL性能测试。不管你的成绩如何,一定要阅读那些带有信息的结果。 限制工作数据集的大小 检查那些SELECT语句中用到的表,看看你是否可以应用WHERE子句进行过滤。一个典型的例子是,当表中只有几千行记录时,一个查询能够很好地执行。但随着应用程序的成长,查询慢了下来。解决方案或许非常简单,限制查询来查看当前月的数据即可。 当你的查询语句带有子查询时,注意在子查询的内部语句上使用过滤,而不是在外部语句上。 只选择你需要的字段 额外的字段通常会增加返回数据的纹理,从而导致更多的数据被返回到SQL客户端。另外: •使用带有报告和分析功能的应用程序时,有时报告性能低是因为报告工具必须对收到的、带有详细形式的数据做聚合操作。 •偶尔查询也可能运行地足够快,但你的问题可能是一个网络相关的问题,因为大量的详细数据通过网络发送到报告服务器。 •当使用一个面向列的DBMS时,只有你选择的列会从磁盘读取。在你的查询中包含的列越少,IO开销就越小。 移除不必要的表 移除不必要的表的原因,和移除查询语句中不需要的字段的原因一致。 编写SQL语句是一个过程,通常需要大量编写和测试SQL语句的迭代过程。在开发过程中,你可能将表添加到查询中,而这对于SQL代码返回的数据可能不会有任何影响。一旦SQL运行正确,我发现许多人不会回顾他们的脚本,不会删除那些对最终的返回数据没有任何影响和作用的表。通过移除与那些不必要表的JOINS操作,你减少了大量数据库必须执行的流程。有时,就像移除列一样,你会发现你减少的数据又通过数据库返回来了。 移除外部连接查询 这说起来容易做起来难,它取决于改变表的内容有多大的影响。一个解决办法是通过在两个表的行中放置占位符来删除OUTER JOINS操作。假设你有以下的表,它们通过定义OUTER JOINS来确保返回所有的数据: customer_idcustomer_name 1John Doe 2Mary Jane 3Peter Pan 4Joe Soap

SQL语句编写与优化规范

SQL语句编写与优化规范 1用SELECT查询用具体字段代替“*”,且尽可能只查询需要的字段。 SELECT * FROM DEMO_TABLE; SELECT FIELD1,FILED2 FROM DEMO_TABLE; 2多表查询时,使用表的别名,就可以减少解析的时间并减少那些由列名歧义引起的语法错误 SELECT FIELD1,FILED2 FROMDEMO_TABLE1,DEMO_TABLE2 WHERE T1_ID=T2_ID; SELECT t1.T1_ID=t2.T2_ID; 3用EXISTS替代IN,用NOT EXISTS替代NOT IN SELECT * FROM EMP ( FROM DEPT WHERE LOC = 'MELB'); SELECT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = 'MELB') 4WHERE条件连接顺序,把表关系写在最前 例如Oracle采用自下而上的顺序解析WHERE子句,表之间的条件连接必须写在其他条件之前,把可以过滤掉大量数据的条件写在WHERE子句的最后,按照过滤记录数量的多少 SELECT * FROM A a, B b WHERE a.num>3000 and b.state=2 AND a.ID=b.ID; SELECT * FROM A a, B b WHERE a.ID=b.ID and b.state=2and a.num>3000 5删除全表时,用TRUNCATE替代DELETE 当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况) 而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.

基于索引的SQL语句优化

基于索引的SQL语句优化 一、尽量避免非操作符的使用 通常情况下,为了对指定列建立特定的条件,需要在WHERE子句中使用诸如NOT、!=、<>、!<、!>等操作符,在索引列上使用这些非操作符,DBMS是不使用索引的,可以将查询语句转换为可以使用索引的查询。例: SELECT * FROM ORDERS WHERE ORDERDATE<>1997-l2 转化为:SELECT * FROM ORDERS WHERE ORDERDATE l998-l-l 这样DBMS就能利用索引字段ORDERDATE,大大提高查询效率。 二、避免困难的正规表达式 MATCHES和LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。 例如:SELECT * FROM STUDENT WHERE STUDENT_NUM LIKE “98_ _” 即使在STUDENT_NUM字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM STUDENT WHERE STUDENT_NUM >”98000”,在执行查询时就会利用索引来查询,显然会大大提高速度。如果一定要使用通配符也要避免通配符在搜索字段的首部出现,这种情况下DBMS的优化器不会使用索引[6]。 三、避免在索引列上使用NULL关键字 避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引。即使索引有多列,只要这些列中有一列含有NULL,该列就会从索引中排除,也就是说如果某列存在空值,即使对该列建索引也不会提高性能[7]。 任何在WHERE子句中使用IS NULL或IS NOT NULL的语句,优化器是不允许使用索引的。 四、避免对查询的列使用数学运算 如果在查询列使用数学运算,则DBMS优化器先要处理数学运算也会影响查询效能。例如: (1)SELECT * FROM ORDERDETAILS WHERE QUANTITY*2<50 (2)SELECT * FROM ORDERDETAILS WHERE QUANTITY<25 虽然这两条查询的结果完全相同,但某些情况下第二个语句的执行效率远高于第一个,因此在查询前应将数学运算转化。

SQL语句大批量多表查询优化解决方案

SQL语句大批量多表查询优化方案 我写这个没什么目的,只是分享一下给大家。 此为自己项目当中所碰见的。 当时也很纠结。但是优化过后。经过测试二亿条数据多表查询,在一分钟以内出来,虽然不是很快。但也尽量了。 首先,数据库表中索引如何创建我想大家都知道。 这是百度当中找到的解释已经很详细了。 聚集索引: 聚集索引基于聚集索引键按顺序排序和存储表或视图中的数据行。聚集索引按 B 树索引结构实现,B 树索引结构支持基于聚集索引键值对行进行快速检索。 非聚集索引: 既可以使用聚集索引来为表或视图定义非聚集索引,也可以根据堆来定义非聚集索引。非聚集索引中的每个索引行都包含非聚集键值和行定位符。此定位符指向聚集索引或堆中包含该键值的数据行。索引中的行按索引键值的顺序存储,但是不保证数据行按任何特定顺序存储,除非对表创建聚集索引。 唯一索引: 唯一索引确保索引键不包含重复的值,因此,表或视图中的每一行在某种程度上是唯一的。 聚集索引和非聚集索引都可以是唯一索引。 包含性列索引: 一种非聚集索引,它扩展后不仅包含键列,还包含非键列。 索引视图: 视图的索引将具体化(执行)视图,并将结果集永久存储在唯一的聚集索引中,而且其存储方法与带聚集索引的表的存储方法相同。创建聚集索引后,可以为视图添加非聚集索引。 全文索引: 一种特殊类型的基于标记的功能性索引,由 Microsoft SQL Server 全文引擎(MSFTESQL) 服务创建和维护。用于帮助在字符串数据中搜索复杂的词。 至于语法之类的就不讲解,大家百度一下就有很多。综合在表当中建立索引是靠

大家自己,如何安排才会觉得合理。在此不做建议。 第一部开始。 创建临时虚拟表。也就是用其实就是把一大堆重复用到的SQL语句放在with as 里面,取一个别名,后面的查询就可以用它 这样对于大批量的SQL语句起到一个优化的作用,而且清楚明了 具体实例 WITH BASE AS ( SELECT * FROM MDM_DISTRIBUTOR ) SELECT * FROM BASE 这只是举例一下,在实际情况中,其实就是把一大堆重复用到的SQL语句放在with as 里面,取一个别名,后面的查询就可以用它这样对于大批量的SQL语句起到一个优化的作用,而且清楚明了 为什么要用WITH ,用with好处就是把把复杂的SQL语句全部都放到这里。把他当作一张表,进行查询。 第二部,创建临时表 语法 --创建临时表 SELECT * INTO #TEMP_REPORT_TABLE FROM BASE --删除临时表,最好判断一下是否为空,在进行删除 IF object_id('tempdb..#TEMP_REPORT_TABLE') IS NOT NULL BEGIN DROP TABLE #TEMP_REPORT_TABLE END 最终优化的就是

sql语句优化工具LECCO SQL Expert

sql语句优化工具LECCO SQL Expert 2007-12-17 14:16 软件讲明: 所谓SQL,确实是指Structured Query Language(结构化查询语言),它是目前使用最广泛的数据库语言,用来和数据库打交道,从数据库中得到用户需要的数据。然而要想熟练使用SQL语句,也不是一件简单的事,有些语句使用起来也比较苦恼。如果我们对SQL语句进行优化,那么用户使用起来就会方便许多。 简单来讲,SQL语句的优化确实是将性能低下的SQL 语句转换成达到同样目的的性能优异的SQL语句。人工智能自动SQL优化确实是使用人工智能技术,自动对SQL语句进行重写,找到性能最好的等效SQL语句。 人工智能自动SQL 优化随着人工智能技术的进展和在数据库优化领域应用的深入,在20世纪90年代末终于显现了突破性的进展——人工智能自动SQL优化。目前在商用数据库领域LECCO TechnologyLi mited(灵高公司)拥有该技术并提供使用该技术的自动优化产品——LECCO SQL Expert,其支持Oracle、Sybase、MS SQLServer和IBMDB2数据库平台。该产品针对数据库应用的开发和爱护时期提供了几个专门的模块:S QL语法优化器、PL/SQL集成化开发调试环境(IDE)、扫描器、数据库监视器等。图1 人工智能自动SQL优化示意图其核心模块之一“SQL语法优化器”的工作原理大致如下 一条源SQL语句输入→“人工智能反馈式搜索引擎”对输入的S QL语句结合检测到的数据库结构和索引进行重写,产生N条等效的SQL 语句输出→产生的N条等效SQL语句再送入“人工智能反馈式搜索引擎”进行重写,直至无法产生新的输出或搜索限额满→对输出的SQL语句进行过滤,选出具有不同执行打算的SQL语句(即不同的执行效率)→对得到的S QL语句进行批量测试,找出性能最好的SQL语句。图2 优化前的SQL语句自动优化实例假设我们从源代码中抽取出这条SQL语句

Sql优化or语句

如何优化带or条件的sql ----------本文章转自网络,互相学习,互相帮助 以下为转帖内容: ======================================================================================== ======== 今天在论坛上看到了一个帖子,问题如下: select * from cc where ((a1 ='ffff' and z1='mmmm') or (b1='sss' and z2='nnnn')) and c1 ='ggggg' 其中表有30万行数据,返回的数据10行左右,怎样创建index访问最快。 按照别人的说法测试了一下,步骤如下: create table CC ( A1 VARCHAR2(5), Z1 VARCHAR2(5), B1 VARCHAR2(5), Z2 VARCHAR2(5), C1 VARCHAR2(5) ) insert into cc values('dffd','dfsd','fdf','fdsfs','sfds');--重复插入2097152条,对查询时间可能有影响 SQL> select count(*) from cc; COUNT(*) ---------- 2097160 SQL> set timing on SQL> edit 已写入file afiedt.buf 1 select * from cc 2 where ((a1='ffff'and z1='mmmm') or (b1='sss' and z2='nnnn')) 3* and c1='ggggg'--无索引情况下or查询 SQL> / A1 Z1 B1 Z2 C1 ----- ----- ----- ----- ----- ffff mmmmm sss nnnn ggggg ffff mmmmm sss nnnn ggggg ffff mmmmm sss nnnn ggggg ffff mmmmm sss nnnn ggggg ffff mmmmm sss nnnn ggggg ffff mmmmm sss nnnn ggggg

如何优化sql语句

1.首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用“全表扫描”方式。 可见,执行计划并不是固定的,它是“个性化的”。产生一个正确的“执行计划”有两点很重要: 1)SQL语句是否清晰地告诉查询优化器它想干什么? 2)查询优化器得到的数据库统计信息是否是最新的、正确的? 2.统一SQL语句的写法 对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的。 select * from dual select * From dual 其实就是大小写不同,查询分析器就认为是两句不同的SQL语句,必须进行两次解析。生成2个执行计划。所以作为程序员,应该保证相同的查询语句在任何地方都一致,多一个空格都不行! 3.不要把SQL语句写得太复杂 我经常看到,从数据库中捕捉到的一条SQL语句打印出来有2张A4纸这么长。一般来说这么复杂的语句通常都是有问题的。我拿着这2页长的SQL语句去请教原作者,结果他说时间太长,他一时也看不懂了。可想而知,连原作者都有可能看糊涂的SQL语句,数据库也一样会看糊涂。 一般,将一个Select语句的结果作为子集,然后从该子集中再进行查询,这种一层嵌套语句还是比较常见的,但是根据经验,超过3层嵌套,查询优化器就很容易给出错误的执行计划。因为它被绕晕了。像这种类似人工智能的东西,终究比人的分辨力要差些,如果人都看晕了,我可以保证数据库也会晕的。 另外,执行计划是可以被重用的,越简单的SQL语句被重用的可能性越高。而复杂的SQL语句只要有一个字符发生变化就必须重新解析,然后再把这一大堆垃圾塞在内存里。可想而知,数据库的效率会何等低下。 4.使用“临时表”暂存中间结果 简化SQL语句的重要方法就是采用临时表暂存中间结果,但是,临时表的好处远远不止这些,将临时结果暂存在临时表,后面的查询就在tempdb中了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能。

SQL语句优化方法

1. 选择最有效率的表名顺序, FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.汗颜!!以前以为dimensional table,都是多条记录呢,怪不得以前写的查询速度这么慢。 2. Where子句中的连接顺序.: 数据库采用自下而上的顺序解析Where子句,根据这个原理,表之间的连接必须写在其他Where条件之前, 那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾.HAVING 最后。这个貌似一直这么写的,不过那是在SQLSERVER里面的,前面都是用的JOIN 3. 整合简单,无关联的数据库访问: 如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系),这个我没有体会,貌似都是按照业务逻辑把它们分成了一小块一小块的呢 4. 尽量缩小子查询的结果。 5. 用EXISTS替代IN、用NOT EXISTS替代NOT IN。貌似我做项目的时候只在少数基于条件的表连接才会用EXISTS,基本不用IN 和NOT IN。 6. 避免在索引列上使用计算. Where子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描. 7,用>=替代> 这个我也不是特别明白,>是IS NOT? 8,用UNION替换OR (适用于索引列) 通常情况下, 用UNION替换Where子句中的OR将会起到较好的效果. 对索引列使用OR将造成全表扫描. 注意, 以上规则只针对多个索引列有效. 如果有column没有被索引, 查询效率可能会因为你没有选择OR而降低. 在下面的例子中, LOC_ID 和REGION上都建有索引.这个在项目中我是有遇到过的,我写了个临时表的函数,其他的SQL需要和临时表连接起来,因为业务逻辑比较复杂,连接的时候速度很慢,后来把OR都改成了UNION ALL 9,避免在索引列上使用IS NULL和IS NOT NULL 10,避免改变索引列的类型 11. 需要当心的Where子句: 某些Select 语句中的Where子句不使用索引. 这里有一些例子. 在下面的例子里, (1)‘!=' 将不使用索引. 记住, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中. (2) ‘||'是字符连接函数. 就象其他函数那样, 停用了索引. (3) ‘+'是数学函数. 就象其他数学函数那样, 停用了索引. (4)相同的索引列不能互相比较,这将会启用全表扫描.

索引SQL语句优化★★★

标题 : 基于索引的SQL语句优化之降龙十八掌 第一掌避免对列的操作 3 第二掌避免不必要的类型转换 4 第三掌增加查询的范围限制 4 第四掌尽量去掉"IN"、"OR" 4 第五掌尽量去掉 "<>" 5 第六掌去掉Where子句中的IS NULL和IS NOT NULL 5 第七掌索引提高数据分布不均匀时查询效率 5 第八掌利用HINT强制指定索引 6 第九掌屏蔽无用索引 6 第十掌分解复杂查询,用常量代替变量 7 第十一掌 like子句尽量前端匹配 7 第十二掌用Case语句合并多重扫描 7 第十三掌使用nls_date_format 8 第十四掌使用基于函数的索引 8 第十五掌基于函数的索引要求等式匹配 9 第十六掌使用分区索引 9 第十七掌使用位图索引 9 第十八掌决定使用全表扫描还是使用索引 9 1 前言 客服业务受到SQL语句的影响非常大,在规模比较大的局点,往往因为一个小的SQL语句不够优化,导致数据库性能急剧下降,小型机idle所剩无几,应用服务器断连、超时,严重影响业务的正常运行。因此,称低效的SQL语句为客服业务的‘恶龙’并不过分。数据库的优化方法有很多种,在应用层来说,主要是基于索引的优化。本次秘笈根据实际的工作经验,在研发原来已有的方法的基础上,进行了一些扩充,总结了基于索引的SQL语句优化的降龙十八掌,希望有一天你能用其中一掌来驯服客服业务中横行的‘恶龙’。 2 总纲 l 建立必要的索引 这次传授的降龙十八掌,总纲只有一句话:建立必要的索引,这就是后面降龙十八掌的内功基础。这一点看似容易实际却很难。难就难在如何判断哪些索引是必要的,哪些又是不必要的。判断的最终标准是看这些索引是否对我们的数据库性能有所帮助。具体到方法上,就必须熟悉数据库应用程序中的所有SQL语句,从中统计出常用的可能对性能有影响的部分SQL,分析、归纳出作为Where条件子句的字段及其组合方式;在这一基础上可以初步判断出哪些表的哪些字段应该建立索引。其次,必须熟悉应用程序。必须了解哪些表是数据操作频繁的表;哪些表经常与其他表进行连接;哪些表中的数据量可能很大;对于数据量大的表,其中各个字段的数据分布情况如何;等等。对于满足以上条件的这些表,必须重点关注,因为在这些表上的索引,将对SQL语句的性能产生举足轻重的影响。不过下面还是总结了一下降龙十八掌内功的入门基础,建立索引常用的规则如下: 1、表的主键、外键必须有索引; 2、数据量超过300的表应该有索引; 3、经常与其他表进行连接的表,在连接字段上应该建立索引;

高性能SQL优化总结

SQL 高性能查询优化语句,一些经验总结 1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null; 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num = 0; 2.应尽量避免在 where 子句中使用!=或$amp; 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; 可以改为强制查询使用索引:

数据库性能优化之SQL语句优化

数据库性能优化之SQL语句优化一、问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就可,而是要写出高质量的SQL语句,提高系统的可用性。 在多数情况下,Oracle使用索引来更快地遍历表,优化器主要根据定义的索引来提高性能。但是,如果在SQL语句的where子句中写的SQL代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种SQL语句就是所谓的劣质SQL语句。在编写SQL语句时我们应清楚优化器根据何种原则来删除索引,这有助于写出高性能的SQL语句。 二、SQL语句编写注意问题 下面就某些SQL语句的where子句编写中需要注意的问题作详细介绍。在这些where子句中,即使某些列存在索引,但是由于编写了劣质的SQL,系统在运行该SQL语句时也不能使用该索引,而同样使用全表扫描,这就造成了响应速度的极大降低。

1. 操作符优化 (a) IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。但是用IN的SQL性能总是比较低的,从Oracle执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别: ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。 推荐方案:在业务密集的SQL当中尽量不采用IN操作符,用EXISTS 方案代替。 (b) NOT IN操作符 此操作是强列不推荐使用的,因为它不能应用表的索引。 推荐方案:用NOT EXISTS 方案代替 (c) IS NULL 或IS NOT NULL操作(判断字段是否为空) 判断字段是否为空一般是不会应用索引的,因为索引是不索引空值的。不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是

sql语句优化原则

SQL语句优化原则 数据库性能是整个应用程序性能的重要部分。数据库优化涉及的内容非常广泛,各类数据库都提供众多的性能指标和大量的优化工具。 下面我们简单介绍一下优化的基本概念。 一个运行良好的数据库至少应具有以下特点: 合理的物理结构及硬件能力 合理的物理结构指数据库文件及整个网络的物理分布。硬件能力指是否有足够的硬件资源来完成应用程序功能。合理的物理结构至少带来两个方面的好处: 1、适量的数据冗余,提高数据安全性。 2、平衡磁盘IO,增强数据读写能力。 而足够的硬件能力的作用自然不言而喻。一旦建立好数据库系统并开始运行,数据库的物理结构就不能改变。 合理的系统参数 对应数据库来说,随着数据量的变化,数据库性能也一直处在变化之中,因此数据库建立之初设定的系统参数会变的越来越不合适,有时甚至阻碍了数据库的正常运行,导致性能瓶颈。因此观察性能变化,随时调整系统参数,使数据库一直处于一个良好的运行状态,就成为管理员最重要的日常工作之一。对系统参数的合理调整,常常能将数据库从崩溃的边缘挽救回来。oracle、sqlserver这样的高品质数据库都为系统参数提供了灵活多变的调整方式。一般来说,只要数

据库结构设计不存在重大缺陷,通过后期的调整,都可以使数据库运行在一个良好的状态下。 性能优良的sql语句 sql语句是在程序开发阶段就已经决定了的,由低效率的sql语句给数据库性能带来的问题,往往在数据库开始运行一段时间后才凸现出来(随着数据量的不断增加),但发现后就变的难以改变,成为不可突破的性能瓶颈。因此,作为一名合格的开发人员,应该建立基本的优化概念和良好的编程习惯,从整体上提高应用程序的质量。 同时,提高sql语句的执行效率,是提高整个数据库性能的最立竿见影且价格低廉的方法之一。因为几乎所有的数据库都会不可避免的运行一些效率低下的sql语句。对数据库性能的调整,往往都是从sql语句调优开始的。 下面我们简单介绍数据库是怎么执行sql语句的。 sql语句是唯一从应用程序发送到数据库实例的命令。数据库实例所做的全部工作就是接受、解释和执行sql语句。 在绝大多数情况下,我们并不需要关心sql语句是怎么执行的,这是因为在当前流行的数据库软件中都无一例外的采用了高性能的优化器,而这些优化器在绝大多数的情况下都能将用户某些不合理的sql语句结构转换成更合理的形式,从而有效提高sql的执行效率。 优化器的优化原理有两种:

SQL语句优化建议

SQL语句优化建议(09-12) 第一条 //* ExecutionPlan1.sqlplan 中缺少索引的详细信息 查询处理器估计采用以下索引可以将查询开销减少99.9151%。 */ /* USE [gh60] GO CREATE NONCLUSTERED INDEX [] ON [dbo].[workflow_fileinbox] ([from_id],[isspecial],[issent]) INCLUDE ([id],[flow_id],[user_id],[file_id],[step_id],[branch_id],[isattention],[hurrytimes],[wishdate],[days] ,[startdate],[checkindate],[sentdate],[leaveword],[token]) GO */ 第二条 //* ExecutionPlan1.sqlplan 中缺少索引的详细信息 查询处理器估计采用以下索引可以将查询开销减少50.609%。 */ /* USE [gh60] GO CREATE NONCLUSTERED INDEX [] ON [dbo].[workflow_fileattach] ([file_id]) INCLUDE ([id],[user_id],[outuser_id],[title],[topic_id],[type],[ver],[lastver],[createdate],[startdate],[enddate ],[checkout],[serverfile],[filename],[fileext],[filesize],[descn]) GO */ 第三条 //* ExecutionPlan1.sqlplan 中缺少索引的详细信息 查询处理器估计采用以下索引可以将查询开销减少93.8037%。 */ /* USE [gh60]

相关文档
最新文档