SQL语句优化实践
减少查询的影响结果集,避免出现全表扫描。
影响结果集是SQL优化的核心。影响结果集不是查询返回的记录数,而是查询所扫描的结果数。通过Explain或Desc分析SQL,rows列的值即为影响结果集(还可以通过慢查询日志的Rows_examined后面的数字得到)。
以下是我常用的一些SQL优化策略:
- 去掉不必要的查询和搜索。其实在项目的实际应用中,很多查询条件是可有可无的,能从源头上避免的多余功能尽量砍掉,这是最简单粗暴的解决方案。
- 合理使用索引和复合索引。建索引是SQL优化中最有效的手段。查找、删除、更新以及排序时常用的字段可以适当建立索引。不过要注意,单条查询不能同时使用多个索引,只能使用一个索引。查询条件较多时,可以使用多个字段合并的复合索引。切记,使用复合索引时,查询条件的字段顺序需要与复合索引的字段顺序保持一致。
- 谨慎使用not in等可能无法使用索引的条件。索引也不是什么时候都可以发挥作用的,当出现"not in","!=","like '%xx%'","is null"等条件时,索引是无效的。使用这些条件的时候,请放到能有效使用索引的条件的右边。设计表结构时,个人建议尽可能用int类型代替varchar类型,int类型部分时候可以通过大于或小于代替"!="等条件,同时也方便满足一些需要按类型排序的需求,至于可读性的问题,完善好数据库设计文档才是明智的选择。同时建议把所有可能的字段设置为"not null",并设置默认值,避免在where字句中出现"is null"的判断。
- 不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将无法正确使用索引。尽可能少用MySQL的函数,类似Now()完全可以通过程序实现并赋值,部分函数也可以通过适当的建立冗余字段来间接替代。
- 在where条件中使用or,可能导致索引无效。可用 "union all" 或者 "union" (会过滤重复数据,效率比前者低) 代替,或程序上直接分开两次获取数据再合并,确保索引的有效利用。
- 不使用select * ,倒不是能提高查询效率,主要是减少输出的数据量,提高传输速度。
- 避免类型转换,这里所说的“类型转换”是指where子句中出现字段的类型和传入的参数类型不一致的时候发生的类型转换。
- 分页查询的优化。页数比较多的情况下,如limit 10000,10 影响的结果集是10010行,查询速度会比较慢。推荐的解决方案是:先只查询主键select id from table where .. order by .. limit 10000,10(搜索条件和排序请建立索引),再通过主键去获取数据。
- 统计相关的查询。影响结果集往往巨大,且部分SQL语句本身已经难以优化。因此,应避免在业务高峰期执行统计相关的查询,或者仅在从库中执行统计查询。部分统计数据,可以通过冗余的数据结构保存,同时建议把数据先保存在内存、缓存中(如redis),再按一定策略写入数据库。
不使用任何连表查询,通过分库和分表实现负载均衡。
随着数据量的增加,连表操作往往会导致影响结果集大增,从SQL优化的层面已经解决不了问题了。
此时,分库和分表是解决数据库性能压力的最优选择(具体分库和分表的方案通常结合实际业务的应用场景来确定,此处略过)。这里重点谈,如何更好的实现或者过渡到分库、分表的分布式数据库架构。
核心点就是必须先去除数据表之间的关联,即不用外键,不使用任何连表查询。为了确保不进行连表操作,在设计数据库表结构的时候,就需要设计适度冗余的字段来达到不连表的目的。
对于一些操作日志、支付记录等,设计一些记录用户信息的字段,个人认为其实不能算冗余,毕竟用户信息往往会更改,但是这种类似操作日志的表确实是需要记录用户操作时的信息,并且不需要在用户更新信息时同步更新。
实际开发中,为了实现不进行连表而冗余的字段,往往是需要在原表更新数据的时候同步更新冗余字段的数据的,如果应用层没有对数据表操作做合理封装,这往往是个棘手的问题,也不方便维护。
当然,现在主流的应用框架,一般采用orm的方式处理数据表,所以问题不大。相反,不连表事实上还可以提高开发效率,比如通过用户ID获取用户姓名操作,如果不连表就可以确保各个业务模块都通过同样的方式去获取用户姓名,调用同一个封装好的方法,这样,就能很方便的统一在应用层加入缓存机制或添加统一的业务逻辑。
同时如果要对用户表进行分库分表,通过应用层程序就可以简单平滑的实现。
使用Innodb。
关于Innodb和Myisam对比,我就不多说了。Myisam的表级锁是致命问题,考虑到MySQL已经默认使用Innodb作为数据库引擎,个人建议大部分情况可以直接使用Innodb,其他引擎这里就不详细讨论了。
使用缓存。
1) 尽可能在程序上实现常用数据的缓存,目前主流的应用框架应该都能快速实现缓存的需求。如果在程序上没有实现数据缓存,开启数据库的query cache也是缓解数据库压力的方式之一,如果确认使用,记得定时清理碎片flush query cache。
SQL语句优化实践的更多相关文章
- 重新学习MySQL数据库12:从实践sql语句优化开始
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a724888/article/details/79394168 本文不堆叠网上海量的sql优化技巧或 ...
- 优化数据库的方法及SQL语句优化的原则
优化数据库的方法: 1.关键字段建立索引. 2.使用存储过程,它使SQL变得更加灵活和高效. 3.备份数据库和清除垃圾数据. 4.SQL语句语法的优化.(可以用Sybase的SQL Expert,可惜 ...
- oracle之sql语句优化
oracle之sql语句优化 sql语句的优化 1.在where子句中使用 is null 或 is not null 时,oracle优化器就不能使用索引了. 2.对于有连接的列,即使最有一个是静态 ...
- 数据库 基于索引的SQL语句优化之降龙十八掌(转)
一篇挺不错的关于SQL语句优化的文章,因不知原始出处,故未作引用说明! 1 前言 客服业务受到SQL语句的影响非常大,在规模比较大的局点,往往因为一个小的SQL语句不够优化,导致数据库性能急 ...
- 数据库的优化(表优化和sql语句优化)
在这里主要是分为表设计优化和sql语句优化两方面来实现. 首先的是表设计优化: 1.数据行的长度不要超过8020字节.如果是超过这个长度的话这条数据会占用两行,减低查询的效率. 2.能用数字类型就不要 ...
- MySQL常用SQL语句优化
推荐阅读这篇博文,索引说的非常详细到位:http://blog.linezing.com/?p=798#nav-3-2 在数据库日常维护中,最常做的事情就是SQL语句优化,因为这个才是影响性能的最主要 ...
- 浅谈mysql配置优化和sql语句优化【转】
做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...
- sql语句优化总结
sql语句优化总结 数据库优化的几个原则: 1.尽量避免在列上做运算,这样会导致索引失败: 2.使用join是应该用小结果集驱动大结果集,同时把复杂的join查询拆分成多个query.不然join的越 ...
- MySQL基础操作&&常用的SQL技巧&&SQL语句优化
基础操作 一:MySQL基础操作 1:MySQL表复制 复制表结构 + 复制表数据 create table t3 like t ...
随机推荐
- HttpWebRequest出错 服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF
服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF The server committed a protocol violation. Se ...
- mybatis实战教程(mybatis in action)之四:实现关联数据的查询
有了前面几章的基础,对一些简单的应用是可以处理的,但在实际项目中,经常是关联表的查询,比如最常见到的多对一,一对多等.这些查询是如何处理的呢,这一讲就讲这个问题.我们首先创建一个Article 这个表 ...
- SOA 面向服务的体系结构
SOA:面向服务的体系结构(service-oriented architecture) 是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来. 接口是采 ...
- Files 的值“ < < < < < < < .mine”无效。路径中具有非法字符。
出现这个问题的原因是,用svn时,发生了冲突.解决方法:先解决代码冲突,然后在你的工程OBJ/DEBUG目录下,找到 工程名.csproj.FileListAbsolute.txt的文件打开并删除含有 ...
- 安装Oracle报错,全部为未知!
安装Oracle一开始就报错:需要将以下日志文件发送给管理员,<未知><未知><未知>. 这种问题需要对oracle的setup.exe设置 兼容性.具体如下图:
- 2017微软秋招A题
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 There is an integer array A1, A2 ...AN. Each round you may ch ...
- weblogic端口号修改和内存参数配置
1 端口号修改 如图 是详细路径 注:我用的weblogic版本是10.3 当刚创建完域的时候这个配置文件下没有Listen-port参数 第一次去控制台修改端口后就这个参数了
- i2c 读写
在I2C设备读取,必须是在同一个周期内. 一个例子,可以同时读出两个值 int read_register_double_value(int reg_addr, unsigned char *valu ...
- Cookie实现商品浏览记录--方式二:JS实现
使用Cookie实现商品浏览记录:方式二:JS方法实现cookie的获取以及写入.当某一个产品被点击时,触发JS方法.利用JS方法判断一下,此产品是否在浏览记录中.如果不存在,则将产品ID加入到coo ...
- XE8 & IOS开发之免费证书真机调试:开发证书、AppID、开发授权profile的申请,附Debug真机调试演示(XCode7 Beta版或以上版本适用,有图有真相)
网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 注意,苹果发布Xcode ...