一、问题的提出& s7 D; u4 `' m" F3 j1 i
在应用系统开发初期,因为开发数据库数据斗劲少,对于发芽SQL语句,复杂视图的编写等体味不出SQL语句各类写法的机能口角,; w3 t1 P( E& R2 d( _
可是如不美观将应用系统提交现实应用后,跟着数据库中数据的增添,系统的响应速度就成为今朝系统需要解决的最首要的问题之一。
5 d0 v$ \9 p/ M( z 系统优化一一个很主要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度分歧可以达到上百倍,可见; C3 p+ U. g" k4 c
对于一个系统不是简单地能实现其功能就可,而是要写出高质量的 SQL 语句,提高系统的可用性。; b% C+ m! S k/ d) e
在大都情形下,Oracle使用索引来更快地遍历表,优化器首要按照界说的索引来提高机能。可是,如不美观在SQL语句的where子句中
: ~$ h) |" o( @8 o4 n6 u 写的SQL代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种SQL语句就是所谓的劣质SQL语句。在编写SQL语句时我们5 Z& d8 P1 ~! I
应清嚣张优化器按照何种原则来删除索引,这有助于写出高机能的SQL语句。
( R/ D- A+ L% K 二、SQL语句编写注重问题
0 M# ^" a" t; ^) s2 c2 m4 h 下面就某些SQL语句的where子句编写中需要注重的问题作具体介绍。
S1 w- t/ i% d: ?) Z 在这些where子句中,即使某些列存在索引,可是因为编写了劣质的SQL,系统在运行该SQL语句时也不能使用该索引,而同样使用4 g7 g3 E+ r1 R- G$ O0 d8 v. _+ E
全表扫描,这就造成了响应速度的极大降低。$ a* r% r, s) Y( \. q) y. }$ e
1. IS NULL 与 IS NOT NULL! v2 |# S8 t' a1 O$ m
不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情形下,只要这些列中有一列含有null,! E: k* p) l) P2 ^. o- e+ p' ~
该列就会从索引中解除。也就是说如不美观某列存在空值,即使对该列建索引也不会提高机能。. _$ u( y4 W" Y
任何在where子句中使用is null或is not null的语句优化器是不许可使用索引的。
/ p& z; h4 l" i, v& m! V2 z; t 2. 联接列$ t5 U' Q) h* _& o% l
对于有联接的列,即使最后的联接值为一个静态值,优化器是不会使用索引的。
* m* E' ~! }" ]2 a- T4 t8 e 我们一路来看一个例子,假定有一个职工表(employee),对于一个职工的姓和名分成两列存放(FIRST_NAME和LAST_NAME),' B. o. n6 N, ?
此快要发芽一个叫比尔.克林顿(Bill Cliton)的职工。1 G! b8 f: T! f3 O2 Y! y' M
下面是一个采用联接发芽的SQL语句,
, j# r# J; t9 m! `2 c7 W; F+ F select * from employee
% W0 h! X8 J8 x7 Q4 M; S5 d4 K where
! T q- R. z% o first_name||''||last_name ='Beill Cliton';1 x0 h% B6 ^4 W7 X6 Q! {
膳缦沔这条语句完全可以发芽出是否有Bill Cliton这个员工,可是这里需要注重,系统优化器对基于last_name建树的索引没有
9 Q2 b8 f1 P: \ 使用。
, y, t3 M4 `' r1 n; R 当采用下面这种SQL语句的编写,Oracle系统就可以采用基于last_name建树的索引。) {* H6 A$ t5 C( I! C( x- o
Select * from employee
" L6 e) L) w: d4 C where1 g5 I( Z6 a; B
first_name ='Beill' and last_name ='Cliton';
$ O3 S( i0 Z0 u3 h7 [( g# ~ 碰着下面这种环际遇若何措置呢?如不美观一个变量(name)中存放着Bill Cliton这个员工的姓名,对于这种情形我们又若何避免
' O* i! k* O4 w3 | 全程遍历,使用索引呢?
) }) \$ T, U, R* x) ~( s3 P# B 可以使用一个函数,将变量name中的姓和名分隔就可以了,可是有一点需要注重,这个函数是不能浸染在索引列上。 |