MySQL索引与高性能SQL介绍

  数据库的性能优化最重要的是SQL性能的优化,SQL性能优化主要是通过索引来实现的。


  MySQL默认配置,在InnoDB引擎下,在100万条记录的某表中查询,在未使用索引的条件下,用了4.1秒钟,在使用了索引的条件下用了0.036秒,快了100多倍。如果将相同的查询再运行一次,会发现更快,仅用了0.0007秒,快了5000多倍,因为MySQL会对索引查询结果缓存,所以第二次查询更快。数据库表的记录越多,数据量越大,索引起的作用越大。


  可以通过EXPLAIN语句查看SQL查询语句是否用了索引。例如:

  explain select * from table where field1 = const1


  一些平常使用较频繁的索引优化方法:

  select * from table where field1 = const1
  可以使用field1列上的单索引或以field1列为前导的复合索引

  select * from table where field1 != const1
  不能使用索引,使用不等于符号不能使用索引

  select * from table where field1 is NULL
  不能使用索引,因为NULL值不能被索引

  select * from table where ABS(field1) = const1
  不能使用索引,列上有函数,不能使用该列上的索引

  select * from table where field1 like ‘const1%’
  可以使用索引,like以常量前导,可以使用索引

  select * from table where field1 like ‘%conts1’
  select * from table where field1 like ‘%conts1%’
  不能使用索引

  select * from table where field1 = const1 and field2 = const2
  可以使用复合索引index1(field1, field2) 或index2(field2, field1)

  select * from table where field1 = const1 or field2 = const2
  可以使用索引field1和field2

  Select * from table1 left join table2 on table1.field1 = table2.field1
  可以使用table2的field1列上的索引

  Select * from table where field1 = const1 order by field2
  可以使用复合索引index1(field1, field2),不能使用复合索引index2(field2, field1)

  Select * from table order by field1, field2
  Select * from table order by field1 desc, field2 desc
  可以使用复合索引index(field1, field2)

  Select * from table order by field1 asc, field2 desc
  Select * from table order by field1 desc, field2 asc
  用不上复合索引index(field1, field2)

  Select * from table1 where field1 = (select field1 from table2 where field2 = const)
  可以使用table2上的field2索引和table1上的field1索引

  Select * from table1 where field1 in (select field1 from table2 where field2 = const)
  仅能用table2上的field2索引,用不上table1上的field1索引

  SELECT max(field3) FROM table GROUP BY field1, field2
  可以使用复合索引index(field1, field2, field3)

  对于较长、较复杂的不走索引的SQL语句,如果能分解为两个或两个以上较简单的走索引的SQL语句,可以大大提高SQL执行速度,例如这条语句:
  Select * from table1 where field1 in ( select field1 from table2 )
  由于这条语句带了in,走不了table1表中的field1索引,当table1中的记录很多时,速度会很慢。在in子句结果集较小的情况下,可以将这个语句拆开,分开执行,先执行in中的子句:
  select field1 from table2
  将执行结果放到变量中,例如:$tmp,然后再执行:
  Select * from table1 where field1 in ( $tmp )
  这样的话,就会用到field1索引,速度会很快。在table1表中(InnoDB引擎)有10万条记录的情况下,拆分前这条SQL语句耗时1.3秒,拆分后两条语句加起来仅用了0.046秒,快了近30倍。

  懂的如何利用索引不仅可以写出高效的SQL语句,而且能够站在性能优化的角度进行数据库设计。例如:标注文章表中的精华文章,可以另拆分一个文章精华表,建立一列(此列必须有索引)保存精华文章的ID,这样无论是查询精华文章还是查询文章的精华属性,通过left join走索引连接查询都会很快;有时为了查询速度快,会另拆分一个表放文章内容,因为这样可以大大减少表的大小,数据库表越小查询时扫描表的速度就越快,但是如果所有的查询都能够走索引的话则不需这样,因为走索引不需扫描整个表,通过索引直接定位记录位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值