<b>具体讲授若何编写高性能的 MySQL 语句</b>[MySQL防范]
本文“<b>具体讲授若何编写高性能的 MySQL 语句</b>[MySQL防范]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
在利用系统开辟早期,由于开辟数据库数据对比少,关于查询SQL语句,复杂视图的的编写等领会不出SQL语句各种写法的性能优劣,但是假如将利用系统提交实际利用后,随着数据库中数据的增添,系统的呼应速度就成为目前系统需求办理的最主要的问题之一.系统优化中一个很重要的方面就是SQL语句的优化.关于海量数据,劣质SQL语句和优良SQL语句之间的速度差别可以到达上百倍,可见关于一个系统不是简单地能实现其功效便可,而是要写出高质量的SQL语句,提高系统的可用性.
在大都情形下,Oracle利用索引来更快地遍历表,优化器主要按照定义的索引来提高性能.但是,假如在SQL语句的where子句中写的SQL代码不公道,就会造成优化器删去索引而利用全表扫描,普通就这种SQL语句就是所谓的劣质SQL语句.在编写SQL语句时我们应清楚优化器按照何种原则来删除索引,这有助于写出高性能的SQL语句.
下面就某些SQL语句的where子句编写中需求注意的问题作具体介绍.在这些where子句中,即便某些列存在索引,但是由于编写了劣质的SQL,系统在运行该SQL语句时也不能利用该索引,而一样利用全表扫描,这就造成了呼应速度的极大降低.
1. IS NULL 与 IS NOT NULL:
不能用null作索引,任何包含null值的列都将不会被包含在索引中.即便索引有多列这样的情形下,只要这些列中有一列含有null,该列就会从索引中解除.也就是说假如某列存在空值,即便对该列建索引也不会提高性能.
任安在where子句中利用is null或is not null的语句优化器是不答应利用索引的.
2. 联接列:
关于有联接的列,即便最后的联接值为一个静态值,优化器是不会利用索引的.我们一同来看一个例子,假定有一个职工表(employee),关于一个职工的姓和名分成两列存放(FIRST_NAME和LAST_NAME),目前要查询一个叫比尔.克林顿(Bill Cliton)的职工.
下面是一个采取联接查询的SQL语句,
|
上面这条语句完好可以查询出能否有Bill Cliton这个员工,但是这里需求注意,系统优化器对基于last_name成立的索引没有利用.
当采取下面这种SQL语句的编写,Oracle系统便可以采取基于last_name成立的索引.
|
碰到下面这种情形又若何处理呢?假如一个变量(name)中存放着Bill Cliton这个员工的姓名,关于这种情形我们又若何避免全程遍历,利用索引呢?可以利用一个函数,将变量name中的姓和名脱离便可以了,但是有一点需求注意,这个函数是不能作用在索引列上.下面是SQL查询脚本:
|
3. 带通配符(%)的like语句:
一样以上面的例子来看这种情形.目前的需求是这样的,要求在职工表中查询名字中包含cliton的人.可以采取以下的查询SQL语句:
select * from employee where last_name like '%cliton%'
这里由于通配符(%)在搜索词首呈现,所以Oracle系统不利用last_name的索引.在很多情形下大概无法避免这种情形,但是一定要心中有底,通配符如此利用会降低查询速度.但是当通配符呈目前字符串其他位置时,优化器就可以操纵索引.在下面的查询中索引得到了利用:
select * from employee where last_name like 'c%'
4. Order by语句:
ORDER BY语句决意了Oracle若何将返回的查询后果排序.Order by语句对要排序的列没有什么分外的限制,也可以将函数加入列中(象联接大概附加等).任安在Order by语句的非索引项大概有计算表达式都将降低查询速度.
细心查抄order by语句以找出非索引项大概表达式,它们会降低性能.办理这个问题的办法就是重写order by语句以利用索引,也可认为所利用的列成立别的一个索引,同时应绝对避免在order by子句中利用表达式.
5. NOT:
我们在查询经常常在where子句利用一些逻辑表达式,如大于、小于、等于以及不等于等等,也可以利用and(与)、or(或)以及not(非).NOT可用来对任何逻辑运算标记着反.下面是一个NOT子句的例子:
... where not (status ='VALID')
假如要利用NOT,则应在取反的短语前面加上括号,并在短语前面加上NOT运算符.NOT运算符包含在别的一个逻辑运算符中,这就是不等于(<>)运算符.换句话说,即便不在查询where子句中显式地加入NOT词,NOT仍在运算符中,见下例: where status <>'INVALID'
再看下面这个例子:select * from employee where salary<>3000;
对这个查询,可以改写为不利用NOT:select * from employee where salary<3000 or salary>3000;
固然这两种查询的后果一样,但是第二种查询筹划会比第一种查询筹划更快些.第二种查询答应Oracle对salary列利用索引,而第一种查询则不能利用索引.
6. IN和EXISTS:
有时刻会将一列和一系列值相对比.最简单的办法就是在where子句中利用子查询.在where子句中可以利用两种格局的子查询.
第一种格局是利用IN操作符: ... where column in(select * from ... where ...);
第二种格局是利用EXIST操作符: ... where exists (select 'X' from ...where ...);
我相信绝大大都人会利用第一种格局,因为它对比简单编写,而实际上第二种格局要远比第一种格局的效率高.在Oracle中可以几近将全部的IN操作符子查询改写为利用EXISTS的子查询.
第二种格局中,子查询以‘select 'X'开始.应用EXISTS子句不管子查询从表中抽取什么数据它只查看where子句.这样优化器就没必要遍历整个表而仅按照索引便可完成工作(这里假定在where语句中利用的列存在索引).相关于IN子句来说,EXISTS利用相连子查询,构造起来要比IN子查询艰难一些.
通过利用EXIST,Oracle系统会首先查抄主查询,然后运行子查询直到它找到第一个匹配项,这就节俭了时间.Oracle系统在履行IN子查询时,首先履行子查询,并将得到的后果列表存放在在一个加了索引的暂时表中.在履行子查询之前,系统先将主查询挂起,待子查询履行完毕,存放在暂时表中今后再履行主查询.这也就是利用EXISTS比利用IN普通查询速度快的缘由.
同时应尽大概利用NOT EXISTS来替换NOT IN,固然二者都利用了NOT(不能利用索引而降低速度),NOT EXISTS要比NOT IN查询效率更高.
以上是“<b>具体讲授若何编写高性能的 MySQL 语句</b>[MySQL防范]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:本文地址: | 与您的QQ/BBS好友分享! |