数据库性能优化之SQL优化
网上有关SQL优化的方案有很多,但多是杂乱无章。近日闲暇抽空整理了一下,方便大家以后的查阅,若发现其中有什么问题和不全,欢迎大家在下面纠正和补充:
1. 对于SQL语句的性能优化,主要体现在对于查询语句的优化上,要尽量避免全表扫描,首先需要注意的就是在 where 和 order by 涉及的列上添加索引,索引的作用就相当于告诉数据库直接从哪里取数 据就可以了,不用全部查找一遍;
2. 慎用 in 和 not in,使用 in 写出来的SQL的优点是比较容易写及清晰易懂, 但是用 in 的SQL语句执行效率非常低,下面是一个例子:
SELECT d.eid FROM dept d WHERE d.eid IN (SELECT e.eid FROM employee e)
使用 exists 代替 in 是一个不错的选择:
SELECT d.eid FROM dept d WHERE EXISTS (SELECT 1 FROM employee e WHERE e.eid = d.eid)
同理,not in 也用not exists 来替代;
3. 尽量避免在 SQL语句中对字段进行 NULL 值判断,对NULL值的判断会导致引擎放弃使用索引而去做全表扫描,推荐做法为:用其它相同功能的操作运算来代替;例如:
SELECT e.name, e.sex, e.addr FROM employee e WHERE e.eid IS NOT NULL
优化方案为: SELECT e.name, e.sex, e.addr FROM employee e WHERE e.eid > 0
总之,最好不要给数据库留下 NULL 值,使用 NOT NULL 填充数据库;
4. 尽量不要用between .. and ... ,使用 >= 和 <= 来代替:
SELECT d.did, d.dno, d.eid FROM dept d WHERE d.did BETWEEN 1 AND 5
替换为: SELECT d.did, d.dno, d.eid FROM dept d WHERE d.did >= 1 AND d.did <= 5 ;
5. LIKE操作符可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好会产生性能上的问题,例如使用含有 like '%bc%' 的语句进行查询的时候不会引用索引,而使用
like 'bc%' 可以使用索引,虽然在很多情况下可能无法避免这种情况,但是一定要心中有底,通配符如此使用会降低查询速度。
6. 尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引而另外一个字段没有索引,将导致数据库引擎放弃放弃使用索引而进行全表扫描,例如:
SELECT d.dname FROM dept d WHERE d.did = 1 OR d.eid = 1001
可以换成: SELECT d.dname FROM dept d WHERE d.did = 1 UNION SELECT d.dname FROM dept d WHERE d.eid = 10017. 使用 group by 时, 最好先把不用的数据排除掉,缩小查询的范 围,从而提升查询效率。可以先在 where 条件里面排除无关数据,然后再进行 group by 操作。
8. 尽量避免在 where 子句中对字段进行表达式或函数操作,这将导致引擎放弃使用索引而进行全表搜索;
9. 如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立 访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。
SELECT d.dname FROM dept d WHERE d.did = @did
解决的办法是强制使用索引:SELECT d.dname FROM dept d WITH(INDEX(索引名)) WHERE d.did = @did
10. 在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序 相一致。
11. 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而 定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。
12. Update 语句,如果只更改1、2个字段,不要 Update 全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。
13. 对于 UNION 操作符,UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。而实际大部分应用中是不会产生重复的记录。
SELECT * FROM dept UNION SELECT * FROM emp
这个SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。推荐做法是在已知没有重复记录的前提下,使用 UNION ALL 操作符替代 UNION,因为 UNION ALL 操作只是简单的将两个结果合并后就返回。14. 不要用 select * from 【表名】 ,用select 【列名】 from 【表名】 ,不要返回用不到的字段。除非不知道表字段时测试用。
15. 程序进行select 时,后面都要commit,这会释放占用的资源。
16. 尽量不要使用游标,因为游标的效率较低,使用游标不仅占用内存,而且还用不可思议的方式锁定表,它们可以使DBA所能做的一切性能优化等于没做。游标里每执行一次fetch就等于执行一次select。游标并不是不可使用,但如果游标操作的数据超过一万行,就应该考虑改写了。
17. 复杂的SQL往往会消耗大量的资源,能用函数解决,就用函数。
18. 尽量避免大事物操作,提高系统的并发能力。
数据库性能优化之SQL优化的更多相关文章
- MySql数据表设计,索引优化,SQL优化,其他数据库
MySql数据表设计,索引优化,SQL优化,其他数据库 1.数据表设计 1.1数据类型 1.2避免空值 1.3text类型优化 2.索引优化 2.1索引分类 2.2索引优化 3.SQL优化 3.1分批 ...
- DB-SQL-MySQL-杂项-调优:Mysql千万以上数据优化、SQL优化方法
ylbtech-DB-SQL-MySQL-杂项-调优:Mysql千万以上数据优化.SQL优化方法 1.返回顶部 1. 1,单库表别太多,一般保持在200以下为宜 2,尽量避免SQL中出现运算,例如se ...
- DBA 需要知道N种对数据库性能的监控SQL语句
--DBA 需要知道N种对数据库性能的监控SQL语句 -- IO问题的SQL内部分析 下面的DMV查询可以来检查当前所有的等待累积值. Select wait_type, waiting_tasks_ ...
- 数据库性能调优——sql语句优化(转载及整理) —— 篇2
下面是在网上搜集的一些个人认为比较正确的调优方案,如有错误望指出,定虚心改正 (1) 选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE 的解析器按照从右到左的顺序处理FROM子句中 ...
- 数据库性能调优——sql语句优化(转载及整理) —— 篇1
一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实 ...
- MySQL 数据库性能优化之SQL优化
前言 有人反馈之前几篇文章过于理论缺少实际操作细节,这篇文章就多一些可操作性的内容吧. 注:这篇文章是以 MySQL 为背景,很多内容同时适用于其他关系型数据库,需要有一些索引知识为基础. 优化目标 ...
- MySQL 数据库性能优化之SQL优化【转】
优化目标 减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑, ...
- 百倍性能的PL/SQL优化案例(r11笔记第13天)
我相信你是被百倍性能的字样吸引了,不过我所想侧重的是优化的思路,这个比优化技巧更重要,而结果嘛,其实我不希望说成是百倍提升,“”自黑“”一下. 有一个真实想法和大家讨论一下,就是一个SQL语句如果原本 ...
- 大数据量数据库设计与优化方案(SQL优化)
转自:http://blog.sina.com.cn/s/blog_6c0541d50102wxen.html 一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的 ...
随机推荐
- django模板的变量,标签,过滤器和自定义过滤器,注释
模板的作用是计算并输出: {{ 变量}} 当模版引擎遇到点如book.title,会按照下列顺序解析: 1.字典book['title'] 2.先属性后方法,将book当作对象,查找属性title,如 ...
- pyhton新手学习之增删改查
一 .列表的定义 1.列表的定义 names = [ "xiajiqni", "test", "wangwu","oldb ...
- Linux字符设备驱动--No.2
分析中断注册函数:request_irq int butsOpen(struct inode *p, struct file *f) { int irq; int i; ; printk(KERN_E ...
- linux线程篇 (二) 线程的基本操作
线程 进程 标识符 pthread_t pid_t 获取ID pthread_self() getpid() 创建 pthread_create() fork 销毁 pthread_exit() ...
- linux进程篇 (三) 进程间的通信1 管道通信
通信方式分4大类: 管道通信:无名管道 有名管道 信号通信:发送 接收 和 处理 IPC通信:共享内存 消息队列 信号灯 socke 网络通信 用户空间 进程A <----无法通信----> ...
- Codeforces Round #490 (Div. 3) :F. Cards and Joy(组合背包)
题目连接:http://codeforces.com/contest/999/problem/F 解题心得: 题意说的很复杂,就是n个人玩游戏,每个人可以得到k张卡片,每个卡片上有一个数字,每个人有一 ...
- mySQL安装的时候一直卡在starting server这里解决办法
昨天安装mySQL的时候一直卡在了starting server这里,等了半天都没反应,后来就去网上寻找解决办法,大部分是说什么设置mysql本地启动服务啊,删除注册表啊,这些办法都试过了 然并卵. ...
- 堪称最好的A*算法(转)
如此好贴,不能不转!原文地址:http://dev.gameres.com/Program/Abstract/Arithmetic/AmitAStar.mht 中文译文转自:http://blog.c ...
- nio之netty5应用
1.netty5和netty4的区别不是很大,但是与netty3差别还是有的.这里不介绍netty4,因为和netty5的方式都差不多.netty5的复杂性相对于netty3要多很多了.基本上架构都被 ...
- 鸡啄米:C++编程之十三学习之类与对象,类的声明,成员的访问控制
1. 本次学习鸡啄米课程第13篇,把比较重要的学习记录下来,以敦促自己更好的学习.推荐他们的网址学习:http://www.jizhuomi.com/school/c/97.html 2. 在面向过程 ...