精华内容
下载资源
问答
  • SQL调优

    2013-12-14 18:10:52
    SQL调优
  • sql调优 sql调优

    2009-11-26 01:29:06
    sql调优.rar sql调优.rar sql调优.rar sql调优.rar
  • sql 调优

    2019-07-23 14:44:57
    sql调优方法 今天来简单介绍一下自己平时在项目开发过程中常用到的sql调优方法,如果项目中用到高并发、多线程等就需要 sql 调优,避免数据库 CRUD 过慢,影响用户体验。 1、对查询进行优化,应尽量避免全表扫描,...

                                             sql调优方法

    今天来简单介绍一下自己平时在项目开发过程中常用到的sql调优方法,如果项目中用到高并发、多线程等就需要 sql 调优,避免数据库 CRUD 过慢,影响用户体验。

    1、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where order by 涉及的列上建立索引。

    2、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

      select id from s where num is null 可以在num上设置默认值0,确保表中num列没有null值,

    然后这样查询: select id from s where num = 0

    3、应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。

    4、应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from s where num=10 or num=20 可以这样查询: select id from s where num=10 union all select id from s where num=20

    5、in 和 not in 也要慎用,否则会导致全表扫描,如: select id from t where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了: select id from s where num between 1 and 3

    6、下面的查询也将导致全表扫描: select id from s where name like '%abc%'

    7、应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如: select id from s where num/2=100 应改为: select id from s where num=100*2

    8、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如: select id from s where substring(name,1,3)='abc'--name以abc开头的id 应改为: select id from s where name like 'abc%'

    ( % 表示匹配 0 - n 个字符,前面不加 % 查询速度快是因为会直接查询abc 开头的字段)

    9、不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

    10、在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引, 否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

    11、不要写一些没有意义的查询,如需要生成一个空表结构: select col1,col2 into #t from s where 1=0 这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样: create table #t(...)

    12、很多时候用 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)

    13、并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引, 如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

    14、索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率, 因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。 一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

    15、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。 这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

    16、尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间, 其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

    17、任何地方都不要使用 select * from s ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

    18、避免频繁创建和删除临时表,以减少系统表资源的消耗。

     

    我是进阶的球儿,大家一起2019年的爬坑历程。感觉分享很给力的话给个赞,谢谢!!!有问题也可以下方留言沟通。

     

     

    展开全文
  • sql调优

    2018-02-17 12:46:20
    sql调优目的:增加sql运行效率。sql调优方式:1、利用SGA共享池机制会缓存解析过的sql,我们可以用动态sql,同时注意每次编写sql遵循同一规范:大小写一致 空格位置一致 表别名一致2、利用oracle解析的规则:从右到左...

    sql调优目的:增加sql运行效率。

    sql调优方式:

    1、利用SGA共享池机制会缓存解析过的sql,我们可以用动态sql,同时注意每次编写sql遵循同一规范:大小写一致 空格位置一致 表别名一致

    2、利用oracle解析的规则:从右到左、从下到上,我们可以将from后面的多张表,按照记录最少的表排在最后,即基础表放在最后面;我们可以把多个where条件中,能筛选掉最多记录的条件放在最后。

    3、根据oracle的sql解析过程分析

    3.1 我们要避免使用全量模糊查询,尽可能明确要查询的列。如:避免使用*,因为使用*,解析器要先去字典表查询要查询的所有列,然后再进一步进行查询动作。(耗费时间)

    3.2 注意部分比较符号的使用:

          1)用>=代替>(前者会直接跳到第一个等于的位置,后者会先跳到第一个等于的位置,再扫描出第一个大于的位置)

          2)is null/is not null /or/in/not in这些要么影响索引正常的使用要么直接不用索引,所以慎用这些关键字

    展开全文
  • 我想与大家分享一些SQL调优技术(简单但有效)。 SQL调优技巧 Oracle技巧会议#6 3/31/98 Kathy Gleeson ________________________________________ SQL是Oracle系统的心脏。 您可以使用许多不同SQL语句来达到...

    sql 调优有哪些技巧

    你好

    我从几个方面受益于本网站。 我想与大家分享一些SQL调优技术(简单但有效)。

    SQL调优技巧 Oracle技巧会议#6 3/31/98 Kathy Gleeson

    ________________________________________

    SQL是Oracle系统的心脏。 您可以使用许多不同SQL语句来达到相同的结果。 在通常情况下,在给定情况下,只有一个语句是最有效的选择。 下面的技巧包括有关一种形式的语句是否总是效率更高或每种语句是否可以替代的信息,并且效率会根据您的应用程序而有所不同。

    Oracle分两个步骤处理SQL:解析和执行。 调优可以通过减少解析,执行或同时减少两者来加快SQL的速度。 请注意,仅在代码正常工作后才能进行SQL调整。 请注意,编写高效SQL与可理解SQL之间不可避免地会发生拔河。

    提示1(最佳技巧):除非SQL完全相同,否则无法在Oracle中共享SQL。 语句必须完全匹配,以防在Oracle内存中共享大小写和基础架构对象。 Oracle避免在以后每次使用相同的语句时进行解析。

    sql>从ID为212的S_CUSTOMER中选择名称; 符合条件的陈述

    sql>从s_customer中选择名称WHERE ID = 212; 小写

    sql>从S_CUSTOMER WHERE ID = 212中选择名称; 空格

    sql>选择名称

    来自S_CUSTOMER

    WHERE ID = 212; 空格

    o在应用程序中使用SQL标准。 像下面这样的规则很容易实现,并且将允许在Oracle内存中进行更多共享。

    -对所有SQL动词使用一种情况

    -在所有行上开始所有SQL动词

    -初始SQL动词内的左右对齐动词

    -用单个空格分隔所有单词

    o使用绑定变量。 对于两个被视为相同的语句,绑定变量的值不必相同。 在成功解析语句之前,不会替换绑定变量。

    可共享SQL

    选择*从emp哪里emp_no =:B1; 绑定值:123

    选择*从emp哪里emp_no =:B1; 绑定值:987

    不可共享SQL

    选择*从emp WHERE emp_no = 123;

    选择*从emp哪里emp_no = 987;

    o使用标准方法来表别名。 如果两个相同SQL语句由于相同的表具有两个不同的别名而有所不同,则该SQL是不同的,将不会共享。

    o使用表别名,并在查询中涉及多个表时,为所有列名加上别名前缀。 如果有人将一个列添加到与另一个表中的列同名的表中,这会减少解析时间并防止将来出现语法错误。 (ORA-00918:歧义定义的列)

    提示2:提防根本不使用索引的WHERE子句。 即使本节中包含的WHERE子句引用的列上有索引,Oracle也会忽略该索引。 所有这些WHERE子句都可以重写为使用索引,同时返回相同的值。 换句话说,不要对WHERE子句中引用的数据库对象执行操作。

    请勿使用

     
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE SUBSTR(account_name,1,7) = 'CAPITAL';     
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE account_name LIKE 'CAPITAL%'; 
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE account_name = NVL ( :acc_name, account_name);     
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE account_name LIKE NVL ( :acc_name, '%'); 
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE TRUNC (trans_date) = TRUNC (SYSDATE);     
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE trans_date BETWEEN TRUNC (SYSDATE) AND TRUNC (SYSDATE) + .99999; 
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE account_name || account_type = 'AMEXA';     
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE account_name = 'AMEX' 
    AND account_type = 'A'; 
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE amount + 3000 < 5000;     
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE amount < 2000; 
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE amount != 0;     
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE amount > 0; 
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE amount NOT = 0;     
    SELECT account_name, trans_date, amount 
    FROM transaction 
    WHERE amount > 0; 
    提示3:不要忘记调整视图。 视图是SELECT语句,可以通过与其他任何类型的SELECT语句相同的方式进行调整。 适用于任何SQL语句的所有调整都同样适用于视图。

    提示4:避免在SELECT语句中包含HAVING子句。 仅在获取所有行之后,HAVING子句才会过滤选定的行。 使用WHERE子句有助于减少排序,求和等方面的开销。仅当对其应用了汇总操作的列受该子句限制时,才应使用HAVING子句。

    请勿使用

     
    SELECT region, AVG (loc_size) 
    FROM location 
    GROUP BY region 
    HAVING region != 'SYDNEY' 
    AND region != 'PERTH';     
    SELECT region, AVG (loc_size) 
    FROM location 
    WHERE region != 'SYDNEY' 
    AND region != 'PERTH'; 
    GROUP BY region; 
    提示5:最小化查询中的表查找(子查询块)的数量,尤其是在您的语句包含子查询SELECT或多列UPDATE的情况下。

    单独的子查询

     
    SELECT emp_name 
    FROM emp 
    WHERE emp_cat = (SELECT MAX (category) 
    FROM emp_categories) 
    AND emp_range = (SELECT MAX (sal_range) 
    FROM emp_categories) 
    AND emp_dept = 0020; 
    组合子查询
     
    SELECT emp_name 
    FROM emp 
    WHERE (emp_cat, sal_range) 
    = (SELECT MAX (category), MAX (sal_range) 
    FROM emp_categories) 
    AND emp_dept = 0020; 
    提示6:进行多个表联接时,请考虑选择EXISTS,IN和表联接。 这些都不是一直更快的。 这取决于您的数据。 如果此处的绩效不佳,则可能是IN子句。

    (注意,此查询返回部门类别“ A”中每个部门的员工姓名。)

     
    SELECT emp_name 
    FROM emp E 
    WHERE EXISTS ( SELECT 'X' 
    FROM dept 
    WHERE dept_no = E.dept_no 
    AND dept_cat = 'A');
    SELECT emp_name 
    FROM emp E 
    WHERE dept_no IN ( SELECT dept_no 
    FROM dept 
    WHERE dept_no = E.dept_no 
    AND dept_cat = 'A');
    SELECT emp_name 
    FROM dept D, emp E 
    WHERE E.dept_no = D.dept_no 
    AND D.dept_cat = 'A'; 
    提示7:在用于确定一对多关系所有者端信息的查询中,避免在SELECT列表上使用要求DISTINCT限定符的联接。 DISTINCT运算符使Oracle提取满足表联接的所有行,然后对重复的值进行排序和过滤。 EXISTS是一种更快的替代方法,因为Oracle优化器意识到一旦满足了子查询,就无需进一步进行操作并且可以提取下一个匹配的行。

    (注意:此查询返回至少有一名雇员的所有部门编号和名称。)

     
    Do Not Use    Use
    SELECT DISTINCT dept_no, dept_name 
    FROM dept D, 
    emp E 
    WHERE D.dept_no = E.dept_no;    SELECT dept_no, dept_name 
    FROM dept D 
    WHERE EXISTS ( 
    SELECT 'X' 
    FROM emp E 
    WHERE E.dept_no = D.dept_no); 
    提示8:考虑使用UNION ALL代替UNION是否足够。 UNION子句强制在返回第一行之前,对UNION的每个部分返回的所有行进行排序和合并,并对重复项进行过滤。 UNION ALL仅返回所有包含重复项的行,而不必执行任何排序,合并或过滤。 如果您的表是互斥的(不包括重复的记录),或者您不在乎是否返回重复项,那么UNION ALL效率会更高。

    联合所有

     
    SELECT acct_num, balance_amt 
    FROM debit_transactions 
    WHERE tran_date = '31-DEC-95' 
    UNION 
    SELECT acct_num, balance_amt 
    FROM credit_transactions 
    WHERE tran_date = '31-DEC-95';     
    SELECT acct_num, balance_amt 
    FROM debit_transactions 
    WHERE tran_date = '31-DEC-95' 
    UNION ALL 
    SELECT acct_num, balance_amt 
    FROM credit_transactions 
    WHERE tran_date = '31-DEC-95'; 
    提示9:考虑使用DECODE避免重复扫描相同的行或重复连接同一表。 请注意,DECODE不一定更快,因为它取决于您的数据和结果查询的复杂性。 另外,使用DECODE要求您在字段中允许新值时更改代码。
     
    SELECT COUNT(*) 
    FROM emp 
    WHERE status = 'Y' 
    AND emp_name LIKE 'SMITH%'; 
    ---------- 
    SELECT COUNT(*) 
    FROM emp 
    WHERE status = 'N' 
    AND emp_name LIKE 'SMITH%';
    SELECT COUNT(DECODE(status, 'Y', 'X', NULL)) Y_count, 
    COUNT(DECODE(status, 'N', 'X', NULL)) N_count 
    FROM emp 
    WHERE emp_name LIKE 'SMITH%'; 
    提示10:Oracle在比较不同类型的列时会自动执行简单的列类型转换(或转换)。 根据转换类型的不同,可能不使用索引。 如果您使用的编程语言支持该类型,请确保将程序变量声明为与Oracle列相同的类型。

    数据类型

    哪里

    子句隐式转换索引后的查询

    用过的?

    emp_no

    索引

    数字SELECT ...

    来自emp

    WHERE emp_no ='123'; 选择 ...

    来自emp

    在哪里emp_no = TO_NUMBER('123');

    emp_type

    索引

    varchar2 SELECT ...

    来自emp

    WHERE emp_type = 123; 选择 ...

    来自emp

    在哪里TO_NUMBER(emp_type)= 123; 没有!

    ________________________________________

    翻译自: https://bytes.com/topic/oracle/insights/658579-sql-tuning-tricks

    sql 调优有哪些技巧

    展开全文
  • Sql调优大全

    2018-05-29 10:28:08
    Sql调优大全,世上最全的sql调优攻略,在这里,你可以找到你想要的所有关于sql调优的内容方法,工作内容。
  • 继《高性能SQL调优精要与案例解析》一书谈SQL调优(SQL TUNING或SQL优化),我们今天就谈谈各主流关系库中,占据SQL调优技术和工作半壁江山的、最重要的核心机制之一——索引(index)。我们知道,《高性能SQL调优精要与...

    继《高性能SQL调优精要与案例解析》一书谈SQL调优(SQL TUNING或SQL优化),我们今天就谈谈各主流关系库中,占据SQL调优技术和工作半壁江山的、最重要的核心机制之一——索引(index)。我们知道,《高性能SQL调优精要与案例解析》一书中也再三强调索引对SQL调优的重要性,可是上篇文章中也谈到,只看案例和解决问题的具体方法,而不掌握SQL调优的基础知识,是没有用的,我们必须做到知其然,更要知其所以然,才能做到融会贯通,活学活用,进而将SQL调优技术掌握到炉火纯青的地步。因《高性能SQL调优精要与案例解析》主要以Oracle数据库为基础,对SQL调优技术进行了讲解,上篇文章中,我也说到,各关系库就SQL调优的分析和解决问题的思路、方法和步骤来说,几乎完全一样,只是具体命令、方法和形式有所差别而已。那么据此,我们今天就对各主流关系库的索引机制进行简要阐述,以帮助读者能更加深入理解和掌握《高性能SQL调优精要与案例解析》一书中的内容和精髓,更寄希望能使其他同学多多受益。但关系库中,索引类型不止一种,而不同关系库,相同关系库不同版本之间,也有差别,那么,下面,我们仅就应用最广泛的B*tree索引加以介绍。

    1、Oracle B*tree索引:Oracle中B*Tree索引的组织结构图在《高性能SQL调优精要与案例解析》一书中均有详细描述,这里不再赘述,需要强调的是,Oracle中B*Tree的非叶级块(non-leaf level block )中,存储的只有索引列的键值(单列索引的列值或多列索引的列值组合)最大值和指向下一级叶级块(leaf level block)或非叶级块的指针(pointer),这里的指针,也就是块的文件号+块号。而Oracle中B*Tree的叶级块中,则存储了索引列的键值+ROWID(数据行所在文件号+块号+槽号)这样,通过B*Tree中的键值和ROWID值,就能很容易的通过索引查找到表中的数据行。而Oracle中表对应的段中数据行,则是堆结构(heap),具体见《高性能SQL调优精要与案例解析》。而值得一提的是,Oracle中还有一种特殊的表组织结构,那就是索引组织表(IOT),该类表虽然在Oracle中应用不多,但在其他关系库中,确应用很广,只不过名称和细节不同而已,具体继续看下面的内容。

    2、MYSQL B*Tree索引:大家知道,MYSQL数据库是一种插件数据库,也就是其中的数据存储引擎可以方便的进行插拔,因此,MYSQL中也有多种存储引擎同时存在。因为本文不是专门讲述MYSQL存储引擎的,因此,我们就拿应用最广的INNODB为例来进行说明。INNODB中的B*Tree索引(MYSQL中又称为key),和Oracle中不同的是,根据具体的组织结构,又可分为簇索引(clustered index或primary key index)和非簇索引(secondary index),在innodb中创建一个表时,系统会为表的主键创建一个簇索引,如果不指定一个主键,系统会选定一个唯一非空索引作为主键,如果不存在唯一非空索引,系统也会自动创建一个隐式主键,总之,表的主键非有不可。INNODB中表的数据,都存储在表的簇索引中,具体说,簇索引是一个B*Tree结构,只是叶级页(leaf

    level page)内除了簇索引的键值外,还包含了表中所有的数据列值,因此,INNODB表的数据是有序的。而INNODB表中非簇索引,其叶级块中并不包含数据行的物理地址(类似Oracle中数据行的ROWID),而是包含了表上簇索引中的键值,因此,INNODB中,通过非簇索引查找数据,一般要经历两次键值查找,第一次在非簇索引上,找到簇索引的键值后,再到簇索引上再次查找,才能找到真正要查找的数据行。这里强调的是,INNODB中表的簇索引并不是个可选项。其组织结构和Oracle中的索引组织表类似。

    3.SQL SERVER B*Tree索引:SQL SERVER数据库,作为微软的拳头产品之一,有时也被人们俗称为MSSQL,目前国内外市场有着相当的占有率。MSSQL中的B*Tree索引,和MYSQL中的类似,也分为簇索引(clustered index)和非簇索引(nonclustered index),但和MYSQL中B*Tree索引不同的是,MSSQL中表上的簇索引并非是强制的,也就是,你创建一张表,该表是一张堆表,也就是其对应的段是以堆的形式组织和存储的,堆的概念,《高性能SQL调优精要与案例解析》一书中有详细论述,这里不再赘述。MSSQL中的堆表上,如果你创建了一个簇索引,那么,该表中的数据都被移到该簇索引的叶级页(leaf

    level page)中,并且以该簇索引的键值顺序排序组织和存储,原来的堆不再存在,如果你选择在该表上不创建簇索引,那么,该表就会一直以堆的形式存在。而MSSQL中的非簇索引,因为簇索引的存在与否,其内部组织和机制也分两种情况,当表上存在簇索引时,非簇索引的叶级页中存储的是簇索引的键值,也就是不存在指向相关数据行物理地址的指针;而如果表上不存在簇索引时,非簇索引叶级页中就会存储指向表中相关数据行物理地址的指针(这个指针MSSQL中叫做rid)。而不管表上是否存在簇索引,MSSQL将通过非簇索引查找数据行的行为称为书签查找(bookmark

    lookup),虽然,MSSQL中,一般将主键作为表上的簇索引来进行使用和创建。我们可以看到,MSSQL中的簇索引,在组织结构上和Oracle中的索引组织表及MYSQL中的簇索引相似。

    4.Postgresql B*Tree索引:Postgresql数据库,作为最强大的开源关系库之一,号称免费版的Oracle,但就其应用特点、行锁及MVCC等方面具体内部实现来讲,确实与Oracle有很多相似之处,也可以说是关系库大家族中,和Oracle最相近的一款关系库。上面我们也说到,Postgresql数据库在很多方面和Oracle非常相似,那么,B*Tree索引的组织结构和应用也不例外,Postgresql数据库中的B*Tree索引和Oracle中很相似,也并没有MYSQL和MSSQL数据库中簇索引一说。值得一提的是,Postgresql中的表和索引等数据库对象,都是以单独的文件形式组织和存储,8k大小的数据页也与Oracle中的块不同,Postgresql中的mvcc与Oracle中的实现机制也有很大区别,因为,Postgresql表中数据的前影像数据和当前版本存储在一起,需要定期通过vaccum进行清除。更值得一提的是,因为Postgresql中B*Tree索引中并不存在数据的版本信息,因此,SQL语句的索引覆盖技术并不存在,无论索引列是否能覆盖SQL语句的所有列,都需要回表操作来确认具体数据行的版本信息,虽然,在postgresql9.2版本中引进了scan-only

    scans操作,这虽然在有些时候可以避开回表操作,但需要访问表的VM文件,更关键的是,如果VM文件中的相应位(bit)为unset状态,还是需要回表,因此,鉴于其机制上的局限,该技术实际中价值并没那么大,也许对写少读多的业务,会有一定的价值。

    以上,仅就常用主流关系库索引机制做简要陈述,以帮助各位读者理解《高性能SQL调优精要及案例解析》一书内容,同时,也希望其他同学多多受益。

    点赞 (0)赏分享 (0)

    展开全文
  • 《高性能SQL调优精要与案例解析》一书上市发售以来,很多热心读者就该书内容及一些具体问题提出了疑问,因读者众多外加本人日常工作的繁忙 ,在这里就SQL调优学习进行讨论并对热点问题统一作答。 首先,我们说说...
  • ORACLE_SQL调优

    2018-08-05 23:33:53
    ORACLE_SQL调优老方块出品,深入讲解了ORACLE原理及常见SQL调优技巧

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,592
精华内容 3,836
关键字:

sql调优