• 七夕当然要学会SQL优化好早点下班去找对象


    目录

    1、SQL语句优化概述

    2、有效使用索引

    2.1何时使用索引

    2.2选择索引列及索引类型 

    2.3复合索引中列的排序

    2.4避免对大表进行全表扫描

    3、采用适当的多表连接技术

    4、SQL使用技巧


    1、SQL语句优化概述

            在数据库系统应用初期,由于数据量比较少,很难觉察出SQL语句性能的优劣,但是随着数据库中数据的增加,系统的响应速度就成为系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍。因此,对于一个应用,并不是简单地写出SQL语句就行,而是要写出高质量的SQL语句,提高系统性能。

    2、有效使用索引

    2.1何时使用索引

    使用索引的基本原则为:
    1、查询数据量仅占整个表数据量的 2%~4% ,甚至更低。
    2、以查询字段为基础,表中的行随机均匀分布。 · 以查询字段为基础,表中的行随机排序。
    3、表中列相对较少。
    4、对表的大多数查询都包含相对简单的 WHERE 子句。
    5、缓存命中率低,并且不需要操作系统缓存。

    2.2选择索引列及索引类型 

    为表创建索引时,应该在表的适当列上创建索引。选择索 引列的原则为:
    1、在 WHERE 子句中频繁使用的列上创建索引。
    2、在 SQL 语句中频繁用于连接的列上创建索引。
    3、不要在频繁修改的列上创建索引。
    4、如果 WHERE 子句中的列在函数或表达式中出现,可以考虑在该列上创建函数索引。
    5、如果存在大量并发的 INSERT UPDATE DELETE 语句 访问父表或子表,可以在外键列上创建索引。
    6、如果列值基数大,取值范围广,重复率低,则应该创建B-树索引。
    7、如果列值基数小,取值范围窄,重复率高,则应该创建位图索引。

    2.3复合索引中列的排序

    由于复合索引是创建在多列上的索引,列的合理排序是利用复合索引、提高查询效率的关键。
    创建复合索引要遵循下列原则:
    1、应该选择在 WHERE 子句中频繁使用的列,并且这些列用AND操作符连接。
    2、如果几个查询都使用相同的列的集合,可以考虑在这些列上创建复合索引。
    3、 创建复合索引时,应该将列的使用频率从高到低进行排 序。

    2.4避免对大表进行全表扫描

    为了提高 SQL 语句执行效率,在执行 SQL 语句时要尽量避免进行全表扫描。在下列几种情况下将发生全表扫描:
    1、所查询的表没有索引。
    2、需要返回表中的所有数据。
    3、带有 LIKE 并使用 “%” 的模糊查询。
    4、带有 NOT IN NOT IN OR IS NULL IS NOT  、NULL、 < > 等运算符的查询。

    3、采用适当的多表连接技术

            由于在多表连接查询中Oracle 优化器对表及查询条件的解 释是自下而上进行的,因此SQL 语句中表的顺序以及 WHERE子句中条件的顺序直接影响连接查询的效率。在连接查询中,系统第一个查询的表称为驱动表。 Oracle通常对驱动表进行全表扫描。应该将数据返回百分比高的表作为驱动表或数据量小的表作为驱动表。如果连接的表在连接列上都具有索引,则优化器将FROM 语句中最后的表作为驱动表,否则Oracle 优化器将检查 SQL 语句中每个表的物理大小、索引状态,以确定驱动表,然后选择成本最低的执行计划。

    4、SQL使用技巧

    (1)多使用绑定变量:使用绑定变量的查询语句在第二次查询时,系统可以直接从库缓冲区中获得该语句以前执行时的分析、执行方案,大大提高执行效率
    (2)多使用 TRUNCATE语句删除表中数据:删除表中所有数据时使用TRUNCATE语句替换DELETE语句。由于执行TRUNCATE语句时,并不将被删除的记录信息保存到回滚段中,而是直接释放数据空间,减少了系统资源的调用,缩短执行时间。
    (3)多使用 COMMIT语句:当执行COMMIT语句时,系统会释放当前事务所占用的资源、解锁以及释放日志空间等,提高系统性能。 
    (4)尽量避免排序操作:对查询结果排序将耗费大量的系统资源,因此尽量避免需要排序的查询操作。如带有DISTINCT、UNION、MINUS、INTERSECT、ORDER BY、GROUP BY的SQL语句都需要对查询结果进行一次或多次排序。 
    (5)尽量指定具体的目标列,而不要使用“*”:Oracle在解析SQL语句的过程中,需要通过查询数据字典将“*”依次转换成所有的列名,这意味着耗费更多的时间。
    (6)尽量避免使用 HAVING 子句,多用 WHERE子句:HAVING子句只有在检索出所有记录并进行统计、排序之后才对结果集(组)进行过滤。如果能通过WHERE子句限制记录的数目,就能减少开销,提高效率。
    (7)尽量减少访问数据库的次数:当执行SQL语句时,Oracle数据库都要在内部解析SQL语句、估算索引的利用率、绑定变量、读数据块等。减少访问数据库的次数,就能减少Oracle数据库的工作量。
    (8)尽量使用 EXISTS 替换 IN NOT EXISTS 替换NOT IN:对表查询时,为了满足一个条件,往往需要与另一个表进行连接查询。此时,可以使用EXISTS(或NOT EXISTS)子句,而不需要进行连接查询,从而可以提高查询的效率。在子查询中,NOT IN子句将执行一个内部的排序和合并。由于NOT IN子句需要对子查询中的表执行了一次全表扫描,因此其效率非常低。为了避免使用NOT IN子句,可以把它改写为NOT EXISTS子句。
    (9)使用 EXISTS 替换DISTINCT:如果进行连接查询的两个表具有一对多的关系,如部门表与员工表,那么在SELECT语句中尽量避免使用DISTINCT。可以使用EXISTS替换DISTINCT,得查询更为迅速,因为子查询的条件一旦满足后,立刻返回结果。
    (10)多使用 DECODE函数来减少处理时间:使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。 
    (11)使用 UNION 替换 OR(适用于索引列):通常情况下,使用UNION替换WHERE子句中的OR将会提高查询的效率,因为对索引列使用OR将对表进行全表扫描。
    (12)使用 IN 替换 OR
    (13)使用 UNION ALL 替换UNION:使用UNION短语将两个查询结果合并时,系统先把这两 个结果集以UNION ALL的方式合并,然后对结果进行排序,并将重复记录合并为一条记录。如果用UNION ALL替换UNION,就不需要对合并后的结果集进行排序了,效率因此而得到提高。
    (14)用表连接替换 EXISTS
    (15)避免在索引列上使用 IS NULL IS NOT NULL的判断:对于单列索引,如果索引列值为NULL,索引中将不存在该记录信息。对于复合索引,如果每个列值都为空,索引中不存在该记录的信息;如果至少有一个列值不为空,则索引中存在该记录的信息。
    (16)避免在索引列上使用计算:在WHERE子句中,如果索引列是函数的一部分,那么优化器将不使用索引而使用全表扫描。 
    (17)尽量使用索引的第一个列:如果索引是建立在多个列上的复合索引,只有当它的第一个列被WHERE子句引用时,优化器才会选择使用该索引。当仅引用索引的第二个列时,优化器使用全表扫描而不使用索引。
    (18)尽量使用表的别名:当使用SQL语句进行多表连接查询时,为表起别名,并把别名前缀置于每个列名之前,这样可以减少列名解析时间,同时减少由于列名歧义引起的语法错误。
  • 相关阅读:
    javascript 基本语法(二)
    通达OA与think PHP对接
    基于Python开发的DIY字符画程序(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)
    线性回归(linear regression)
    (STM32)从零开始的RT-Thread之旅--基础项目构建与时钟配置
    多亏了这个神器,让我斩获华为入场券
    git 上传大文件
    小小装饰器大大用处
    vue-生成二维码
    Fragment的生命周期
  • 原文地址:https://blog.csdn.net/jungeCSND/article/details/126153199