原创

mysql优化

Mysql 优化 执行计划

EXPLAIN + SQL语句

  • id相同执行顺序从上到下的顺序

  • select_type 查询的类型:

    • SIMPLE 简单的select查询

    • PRIMARY 查询中最外层的SELECT

    • UNION:UNION操作中,查询中处于内层的SELECT(内层的SELECT语句与外层的SELECT语句没有依赖关系)

    • UNION RESULT:UNION操作的结果,id值通常为NULL

    • DEPENDENT UNION:UNION操作中,查询中处于内层的SELECT(内层的SELECT语句与外层的SELECT语句有依赖关系)

    • SUBQUERY:子查询中首个SELECT(如果有多个子查询存在)

    • DEPENDENT SUBQUERY:子查询中首个SELECT,但依赖于外层的表(如果有多个子查询存在)

    • DERIVED:被驱动的SELECT子查询(子查询位于FROM子句)

    • MATERIALIZED:被物化的子查询

  • table 表名

  • partitions 分区

  • possible_keys 可能用到的索引

  • key 实际用到的索引

  • rows:扫描出的行数(估算的行数)

  • filtered:按表条件过滤的行百分比

语句优化

  • 索引的建立:对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引
  • .应尽量避免在 where 子句中使用!=或<>操作符
  • or的使用方法 如:

EXPLAIN SELECT * FROM biz_article where user_id = 1 or user_id = 2

id	select_type	table	           partitions	type	        possible_keys	key	    key_len	ref	rows	filtered	Extra
1 SIMPLE biz_article range user_index user_index 8 56 100 Using index condition

可以这样查询:

EXPLAIN SELECT * FROM biz_article where user_id = 1 union all SELECT * FROM biz_article where user_id = 2

id	select_type	table	partitions	type	possible_keys	key	        key_len	ref	rows	filtered	Extra
1 PRIMARY biz_article ref user_index user_index 8 const 55 100
2 UNION biz_article ref user_index user_index 8 const 1 100
  • in 和 not in 也要慎用 如:select id from t where num in(1,2,3)对于连续的数值,能用 between 就不要用 in 了:select id from t where num between 1 and 3

  • 左模糊查询会导致全表扫描 select id from t where name like '%abc%'

  • 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

  • 在使用索引字段作为条件时,如果该索引是复合索引,应尽可能的让字段顺序与索引顺序相一致。

  • 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。

  • 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

  • 字符串存储可以用char 或者 varchar,char的长度是不可变的,而varchar的长度是可变的也就是说,定义一个char[10]和varchar[10],如果存进去的是‘csdn’,那么char所占的长度依然为10,除了字符‘csdn’外,后面跟六个空格,而varchar就立马把长度变为4了,取数据的时候,char类型的要用trim()去掉多余的空格,而varchar是不需要的,尽管如此,char的存取数度还是要比varchar要快得多,因为其长度固定,方便程序的存储与查找;但是char也为此付出的是空间的代价,因为其长度固定,所以难免会有多余的空格占位符占据空间,可谓是以空间换取时间效率,而varchar是以空间效率为首位的。

  • 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

正文到此结束