十五年测试老手,长期负责WEB\APP 项目测试,目前主要负责团队管理工作。

MySQL 数据库语句优化的原则

上一篇 / 下一篇  2010-01-28 16:10:33 / 个人分类:mysql

MQ~6Tk*Za0  1、使用索引来更快地遍历表。

m3V%Y x;lz D,f0

pN#q{nq D%Gd0  缺省情况下建立的索引是非群集索引,但有时它并不是最佳的。在非群集索引下,数据在物理上随机存放在数据页上。合理的索引设计要建立在对各种查询的分析和预测上。一般来说:

jf"\qo Uq){%V051Testing软件测试网Go-p?-Z O

  a.有大量重复值、且经常有范围查询( > ,< ,> =,< =)和order by、group by发生的列,可考虑建立群集索引;

+hEnG/C[L0

z D F*p|-x)`0  b.经常同时存取多列,且每列都含有重复值可考虑建立组合索引;

?)G6~$k mA5SL0

-s"mA:[3P)oSO0  c.组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列。索引虽有助于提高性能但不是索引越多越好,恰好相反过多的索引会导致系统低效。用户在表中每加进一个索引,维护索引集合就要做相应的更新工作51Testing软件测试网O:t#?O:o.AO2^(Y X

51Testing软件测试网iq&c(Sf\8j

  2、在海量查询时尽量少用格式转换。51Testing软件测试网,W8Z"I$c |C/kwV

51Testing软件测试网-L VJO3a

  3、ORDER BY和GROPU BY:使用ORDER BY和GROUP BY短语,任何一种索引都有助于SELECT的性能提高。

{n dG.BV SQK0

J*Y#d6D-`NF0  4、任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。51Testing软件测试网6Rw;sE)S$z8`~

51Testing软件测试网#]s0e:P Ux6u*[`3I

  5、IN、OR子句常会使用工作表,使索引失效。如果不产生大量重复值,可以考虑把子句拆开。拆开的子句中应该包含索引。

yh pzU2c#@051Testing软件测试网WI"@2{wc M-?

  6、只要能满足你的需求,应尽可能使用更小的数据类型:例如使用MEDIUMINT代替INT51Testing软件测试网,jIP v&{]Oo8N

%m T8x \Q,]0  7、尽量把所有的列设置为NOT NULL,如果你要保存NULL,手动去设置它,而不是把它设为默认值。51Testing软件测试网-WK*|.?M

.{-B~wMQ VX0  8、尽量少用VARCHAR、TEXT、BLOB类型

)Zk%i*OO've A4Q!k051Testing软件测试网-R2gc:L0G$P T

  9、如果你的数据只有你所知的少量的几个。最好使用ENUM类型

G$WFyW `Bk\0

Hm D3aA/h/xd0  10、正如graymice所讲的那样,建立索引。51Testing软件测试网 |v/nd-HR)H

51Testing软件测试网,{0oQ2eGJ

  以下是我做的一个实验,可以发现索引能极大地提高查询的效率:51Testing软件测试网HN R8Xe]8H4l2b

g-](gJ7eh$C!hu0  我有一个会员信息表users,里边有37365条用户记录:51Testing软件测试网)e cB.N v/_5W

8D{`@h#}0  在不加索引的时候进行查询:

I%WLT4km(oE051Testing软件测试网+Ds%B-kb5s

  sql语句A:

VK5V.cF0

P|-G0m{WB0  代码:

? L'A9cg^[D{,Z0

8\$[g)e$g)}8D u0  select * from users where username like '%许%';

Pk}Ko7E0

TD5qYTI+bZ0  在Mysql-Front中的8次查询时长为:1.40,0.54,0.54,0.54,0.53,0.55,0.54 共找到960条记录51Testing软件测试网;E2g.^*R q%LZEATV

51Testing软件测试网&Bf4WFv%J[ D

  sql语句B:

;`b K v({Xv!d051Testing软件测试网a!B'|h7`/c2o7Si

  代码:

c$uHIB5F051Testing软件测试网d#ku m,PU*w+N

  select * from users where username like '许%';

derq~ O Gi;K b2p051Testing软件测试网:[ c^2Tn:e d"S

  在Mysql-Front中的8次查询时长为:0.53,0.53,0.53,0.54,0.53,0.53,0.54,0.54 共找到836条记录

U{!t4g$MZ@051Testing软件测试网/IJ2xqj3zJ9jE

  sql语句C:51Testing软件测试网-j$qS Ok&`2B~

51Testing软件测试网;A[y*EEU

  代码:

2QMDt+I&CFqu051Testing软件测试网%va3hb+\s2vh]NV

  select * from users where username like '%许';

O\` WU051Testing软件测试网7D)@-D6_^u^T!hV(AQ

  在Mysql-Front中的8次查询时长为:0.51,0.51,0.52,0.52,0.51,0.51,0.52,0.51 共找到7条记录51Testing软件测试网6^ {"{ Bsh.E

51Testing软件测试网xoo2V#rZ+I3~I\d

  为username列添加索引:

)s5i S&gwIB0

2~ `ny(f c&J X!T/jB0  代码:

1Kk;`Cc6E3i051Testing软件测试网#]@g3HHV:o

  create index usernameindex on users(username(6));51Testing软件测试网 f*n:JPpkfO

51Testing软件测试网0{p'iC&Cb

  再次查询:51Testing软件测试网!B;O^)qy)q

(u4V8L_?C"Fgq;x0  sql语句A:51Testing软件测试网 V*SX-_xR'Z C%X

oD'B3se$s:n*b0  代码:51Testing软件测试网 ulKLj,N

51Testing软件测试网8D6x&Vc}c @5H]1{

  select * from users where username like '%许%';51Testing软件测试网VF;sV+X2S

51Testing软件测试网;[9p[h0E(Z0gf8i |s h

  在Mysql-Front中的8次查询时长为:0.35,0.34,0.34,0.35,0.34,0.34,0.35,0.34 共找到960条记录

_LAr5U-E }\$[R$z0

.w8u*u r%W,D1{,zl0  sql语句B:51Testing软件测试网3pY/a ?8zM

51Testing软件测试网py*w!eK4Z)Z4W)]

  代码:

J_.~ e1W7}V*k~051Testing软件测试网6nGR-I6o7K/N Y

  select * from users where username like '许%';51Testing软件测试网 PB'ek e!b!t9wU0v&n

51Testing软件测试网)xC imo-j7}hZ

  在Mysql-Front中的8次查询时长为:0.06,0.07,0.07,0.07,0.07,0.07,0.06,0.06 共找到836条记录

/gC[,M5Fd0

!I xdt+J0  sql语句C:

,^#Y8I%C:J'i.Yl l!wg051Testing软件测试网 nT xb%K`

  代码:51Testing软件测试网a,e5\tGKZUj

51Testing软件测试网 j@ob7[G}sX-B

  select * from users where username like '%许';

]1[/p!bD1Y%\8f)l0

E M)BHg.A#Kzh2D(I GZ0  在Mysql-Front中的8次查询时长为:0.32,0.31,0.31,0.32,0.31,0.32,0.31,0.31 共找到7条记录51Testing软件测试网"\.\_M0R,[-c

[p.@%QmS g0  在实验过程中,我没有另开任何程序,以上的数据说明在单表查询中,建立索引的可以极大地提高查询速度。51Testing软件测试网F[m-Tqj3tv

w1d)z9e(kF;g0  另外要说的是如果建立了索引,对于like '许%'类型的查询,速度提升是最明显的。因此,我们在写sql语句的时候也尽量采用这种方式查询。

niU'mV t['Y0

sH i~W0  对于多表查询我们的优化原则是:

j:P!dww u b6h0

Fx2zrDB'a_0  尽量将索引建立在:left join on/right join on ... +条件,的条件语句中所涉及的字段上。51Testing软件测试网Av p'u+F:g{1S

)Z,S\ Z"JMI4@0  多表查询比单表查询更能体现索引的优势。51Testing软件测试网gp;b&l |:v*p2`X?

{ X4@ QtZ0  11、索引的建立原则:51Testing软件测试网R:T` k(][|`

51Testing软件测试网,DSZ [7XAsb C|}

  如果一列的中数据的前缀重复值很少,我们最好就只索引这个前缀。Mysql支持这种索引。我在上面用到的索引方法就是对username最左边的6个字符进行索引。索引越短,占用的 磁盘空间越少,在检索过程中花的时间也越少。这方法可以对最多左255个字符进行索引。51Testing软件测试网2[L(I*R x)G5S `

51Testing软件测试网c!X+^1v7K4W1[&M

  在很多场合,我们可以给建立多列数据建立索引。51Testing软件测试网-Mm%|4}-]5O(N5U

51Testing软件测试网lE5Qg \)UG

  索引应该建立在查询条件中进行比较的字段上,而不是建立在我们要找出来并且显示的字段上

5vcZJGzk051Testing软件测试网2f aU)b R9Cm

  12、一往情深问到的问题:IN、OR子句常会使用工作表,使索引失效。如果不产生大量重复值,可以考虑把子句拆开。拆开的子句中应该包含索引。

ap"bLt }kV051Testing软件测试网ITH*@BE/|

  这句话怎么理解决,请举个例子51Testing软件测试网!qF%Zeo,R-^n:c

5h7z$Th&P@$T7ZB|0  例子如下:

;^(eu$iHf2H,[[4L0

8O5n6| D8_Y']"^4@3_0  如果在fields1和fields2上同时建立了索引,fields1为主索引

aL*H"J.W*B+T051Testing软件测试网!h(`*\,X2|d

  以下sql会用到索引

ZH Cek,UQ0Bg0

H1cT!V-Pi"\0  代码:51Testing软件测试网,Vv+t7wu

9aBp-K^J0  select * from tablename1 where fields1='value1' and fields2='value2'

wqH.Zkr{o;N0

1w6Y [-R%M.Xwx |0  以下sql不会用到索引

U'n1xAr*bF2^Y+qR051Testing软件测试网e(e/}v@

  代码:

3fX&L2V4\8bX;y0

NM zBzQ4l0  select * from tablename1 where fields1='value1' or fields2='value2'51Testing软件测试网X w1Xt/_4|jNF$r

51Testing软件测试网:c;x{Jx

  13.索引带来查询上的速度的大大提升,但索引也占用了额外的硬盘空间(当然现在一般硬盘空间不成问题),而且往表中插入新记录时索引也要随着更新这也需要一定时间。51Testing软件测试网m{.q\&@1N0N

`)`/FW x7y0  有些表如果经常insert,而较少select,就不用加索引了.不然每次写入数据都要重新改写索引,花费时间; 这个视实际情况而定,通常情况下索引是必需的。

|-oi;J#o8v"G4e0

j S4OdHl"S&iMz0  14.我在对查询效率有怀疑的时候,一般是直接用Mysql的Explain来跟踪查询情况。51Testing软件测试网*re8f(p+k3jE I{

#w1X$\)Eo)E~[0  你用Mysql-Front是通过时长来比较,我觉得如果从查询时扫描字段的次数来比较更精确一些。51Testing软件测试网4e5X|f4ng1{.]


TAG: 数据库优化 MySQL mysql

 

评分:0

我来说两句

Open Toolbar