• 浅析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合适,关键是根据实际情况找到权衡点。

  • 相关阅读:
    Linux随笔 DNS搭建
    总算亲自看见了一个网站被黑后的页面。
    [转]XP如何禁止媒体文件预览
    用Word2007发Blog的配置方法(多图)。
    C#通过http访问olap
    测试Word2007
    用IronPython作为.Net的脚本语言。
    用批处理写的显示磁盘剩余空间的小程序。
    事开机时Num Lock键打开。
    快捷方便的对js文件进行语法检查。
  • 原文地址:https://www.cnblogs.com/goloving/p/15220723.html
Copyright © 2020-2023  润新知