SQL优化

  本文分析Mysql中简单查询,通过explain语句进行分析,并给出在Navicat中可使用的完整示例

一、explain介绍

  对sql语句执行explain(explain select t.mc,t.cj from test2 t where t.id =1)返回结果:

  table |  type | possible_keys | key | key_len  | ref | rows | Extra

  这里只介绍两个结果,type和rows

  type:(第一判断标准)
    显示连接使用了何种类型
    从最好到最差的连接类型为:system、const、eg_reg、ref、ref_or_null、 range、indexhe、 ALL
  rows:(为了获取结果扫描的行数,越接近结果行数越好)
    MYSQL认为必须检查的用来返回请求数据的行数

二、sql优化

1.索引问题(索引列失效)

法则:不要在建立的索引的数据列上进行下列操作:

避免对索引字段进行计算操作(包括函数)
避免在索引字段上使用not,<>,!=
避免索引列用 or 连接,这样导致索引列不可用
避免对索引列以%开头的模糊查询
避免在索引列上使用IS NULL和IS NOT NULL
避免在索引列上出现数据类型转换
避免建立索引的列中使用空值

2.其他查询

避免在WHERE子句中使用in,not in,or 或者having(可以使用 exist 和not exist代替 in和not in)
能用union all就不用union,union有个去重的过程
限制使用select * from table

三、示例

1.创建示例表

DROP TABLE IF EXISTS `test2`;
CREATE TABLE `test2` (
  `id` tinyint(4) NOT NULL,
  `mc` varchar(11) NOT NULL,
  `bj` tinyint(4) NOT NULL,
  `cj` varchar(4) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;

INSERT INTO `test2` VALUES ('1', 'z3', '1', '01');
INSERT INTO `test2` VALUES ('2', 'l4', '2', 'Z');
INSERT INTO `test2` VALUES ('3', 'w5', '1', '03');
INSERT INTO `test2` VALUES ('4', 'm6', '2', '04');
INSERT INTO `test2` VALUES ('5', 'z7', '1', 'A');
INSERT INTO `test2` VALUES ('6', 'w8', '2', '06');

2.索引问题

explain select t.mc,t.cj from test2 t where t.id =1;-- type:const

-- 对索引字段计算或者使用函数,索引失效
explain select t.mc,t.cj from test2 t where t.id*2 = 2;-- type:ALL(全局扫描)
explain select t.mc,t.cj from test2 t where sqrt(t.id) = 2;-- type:ALL
explain select t.mc,t.cj from test2 t where CAST(t.id AS char) = '2';-- type:ALL
-- 索引字段使用not,<>,!=索引失效
explain select t.mc,t.cj from test2 t where t.id !=2;-- type:range
explain select t.mc,t.cj from test2 t where t.id <>2;-- type:range

-- 验证模糊查询 以%开头 索引失效
explain select t.mc,t.cj from test2 t where t.mc like 'z%';-- type:ALL
-- 对名称创建索引
CREATE INDEX index_name ON test2 (mc);
explain select t.mc,t.cj from test2 t where t.mc = 'z3';-- type:ref
explain select t.mc,t.cj from test2 t where t.mc like 'z%';-- type:range
explain select t.mc,t.cj from test2 t where t.mc like '%3';-- type:ALL

3.其他查询

-- in 查询,采用exist或者union all
explain select t.mc,t.cj from test2 t where t.id in (1,2);-- type:range
explain select t.mc,t.cj from test2 t where t.id=1 union all select t.mc,t.cj from test2 t where t.id=2
-- or 查询
explain select t.mc,t.cj from test2 t where t.id =1 or t.mc='l4';-- type:ALL
posted @ 2017-06-09 18:16  sailor4518  阅读(180)  评论(0编辑  收藏  举报