• 浅析SQL优化查询性能的最佳实践


    1、在select查询中,只返回需要的列。查询中存在的列越少,则使用的IO和网络带宽就会越少。最好不要使用 * 返回所有: select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

    2、在减少列的同时,也要考虑一下减少行。使用where子句来减少查询返回的行,不要让应用程序在只需显示前10行时,却返回100行。

    3、减少 join 次数

      连接到单个查询中的每个表都会增加额外的开销。虽然具体 join 多少个表会受到数据库设计、容量大小以及用于关联查询的列的影响,但是短小查询有短小查询的好处。

      所以如果存储过程中有一个执行很长时间的非常大的查询,那么可以把这个查询分解为几个更小的中间结果,这通常会显著加快生成结果集的速度。

      另外,减少join次数会降低sql的复杂程度,使得优化器生成更好的执行计划。

     4、只在需要有序结果时,采用 order by。大结果集的排序操作会导致额外开销,如果排序不是必须的那就不要排序

    5、避免在 from、where、having 子句中隐式数据类型的转换

      当谓词中底层数据类型不匹配就会发生隐式数据类型转换,并且是由SQL Server自动转换的。比如,java应用程序发送unicode文本到非unicode列,对于每秒处理数百个事务的程序来说,隐式转换会增加处理时间。

      另外,隐式数据类型的转换可能会导致不能引用索引,导致查询性能下降。

    6、如果去除重复数据不是必须的,那么就不要用 distinct、union,而是用 union all

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

    8、应尽量避免在 where 子句中对字段进行 null 值判断,创建表时NULL是默认值,但大多数时候应该使用NOT NULL,或者使用一个特殊的值,如0,-1作为默认值。

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

      MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE

    10、应尽量避免在 where 子句中使用 or 来连接条件, 否则将导致引擎放弃使用索引而进行全表扫描。

      可以使用 UNION ALL 合并查询: select id from t where num=10 union all select id from t where num=20

    11、in 和 not in 要慎用,否则会导致全表扫描。对于连续的数值,能用 between 就不要用 in 了:Select id from t where num between 1 and 3

    12、使用表的别名(Alias):当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个Column上。这样一来就可以减少解析的时间并减少那些由Column歧义引起的语法错误。

    13、当只要一行数据时使用 LIMIT 1 。

      当你查询表的有些时候,你已经知道结果只会有一条结果,但因为你可能需要去fetch游标,或是你也许会去检查返回的记录数。在这种情况下,加上 LIMIT 1 可以增加性能。这样一样,MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。

    14、尽量用 join 代替子查询

      虽然 Join 性能并不佳,但是和 MySQL 的子查询比起来还是有非常大的性能优势。MySQL需要为内层查询语句的查询结果建立一个临时表。然后外层查询语句在临时表中查询记录。查询完毕后,MySQL需要插销这些临时表。所以在MySQL中可以使用连接查询来代替子查询。连接查询不需要建立临时表,其速度比子查询要快。

    15、避免在where子句中对字段进行表达式操作,会导致引擎放弃使用索引

    16、避免在where子句中对字段进行函数操作

    17、不要where子句的 = 左边进行函数、算术运算或其他表达式运算,系统可能无法正确使用索引

    18、定长类型和变长类型:尽可能用varchar/nvarchar代替char/nchar

      CHAR(M)定义的列的长度为固定的,M取值可以为0~255之间,当保存CHAR值时,在它们的右边填充空格以达到指定的长度。当检索到CHAR值时,尾部的空格被删除掉。在存储或检索过程中不进行大小写转换。CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不足的自动用空格填充。

      VARCHAR(M)定义的列的长度为可变长字符串,M取值可以为0~65535之间,(VARCHAR的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是65,532字节)。VARCHAR值保存时只保存需要的字符数,另加一个字节来记录长度(如果列声明的长度超过255,则使用两个字节)。VARCHAR值保存时不进行填充。当值保存和检索时尾部的空格仍保留,符合标准SQL。varchar存储变长数据,但存储效率没有CHAR高。

      如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。空间上考虑,用varchar合适;从效率上考虑,用char合适,关键是根据实际情况找到权衡点。

  • 相关阅读:
    网站安全防范 关于观看了一个小网站被打的视频感想
    redis的另一个分支 keydb
    数据库并发获取资源并更新状态的时候如何加锁使每人获取的资源不冲突
    mysql8创建用户
    linux找到目录下的大文件
    【其它】从零维到十维空间……(结合简单的图示和通俗的道理来解释)
    三十六计
    【转】学多少年才算“精通Java”
    【转】Java的三种代理模式
    通过ip获取省份城市名称(腾讯地图apis)
  • 原文地址:https://www.cnblogs.com/goloving/p/15220723.html
Copyright © 2020-2023  润新知