mysql查询语句的效率

mysql查询语句的效率

几篇文章的摘录。

为什么MySQL不推荐使用子查询和join(开发程序)

1子查询,效率差。原因:执行子查询时,会创建临时表,查询完毕后再删除它,所以子查询的速度会收到影响。

2JOIN。小表驱动大表,通过索引字段进行关联,只适用较少的数据量。

3从开发程序看,数据库只作为储存数据的工具来用,业务逻辑放到应用控制层上去实现。

推荐,大数据下,为了保证效率,推荐根据索引单表取得数据,然后在程序里面做join, merge数据。??只开发时,在控制层实现业务逻辑??。

MySQL大表优化方案

单表优化:

一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下的表进行单表优化。

除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度。

字段:

  • 适用tinyint, smallint, medium_int代替int, 非负加上unsigned
  • varchar的长度要根据实际需求设定
  • 用enum或int,代替varchar
  • 尽量使用TIMESTAMP而非DATETIME 为什么?(一篇博客)
    • datetime类型适合记录数据的原始的创建时间。
      • 可以为空值。实际储存格式由创表者设定。
      • 和时区无关。
      • 用now()来插入系统的当前时间。
    • timestamp类型适合记录数据的最后修改时间,因为可以设定当其他字段的值变更后,timestamp自动更新。
      • 可以为空值,但不能自定义值。
      • 有时区,可以时区转化。
      • 值的范围是:1970或晚于2037。
      • 值以UTC格式保存。
      • 默认值: current_timestamp()
      • 默认情况下以后任何时间修改表中的记录时,对应记录的timestamp值会自动被更新为当前的系统时间。
  • 单表设计,字段数量要控制,最好20个以内。
  • 避免用null字段, 很难查询优化且占用额外索引空间

索引:

  • 索引根据实际需要来设置,不是越多越好,索引本身是占用内存空间的。
  • 在where和order by上会用到的columns, 是否建立索引,可以使用explain查看是用了索引还是全表扫描
  • 应尽量避免在where上对字段进行null值的判断,否则导致引擎放弃使用索引,而改用全表扫描。
  • 如性别列这种只有男,女,中性三种值的字段/列,无需建立索引。
  • 尽量不用foreign key,用应用程序来保证约束。
  • 尽量不用unique,        用应用程序来保证约束。
  • 使用多列索引时主意顺序和查询条件保持一致,同时删除不必要的单列索引
  • 字符字段只建前缀索引,  字符字段最好不要做主键.

查询:

  • 不做列运算:SELECT id WHERE age + 1 = 10,任何对列的操作都将导致全表扫描,它包括数据库教程函数、计算表达式等等,查询时要尽可能将操作移至等号右边。
  • sql语句尽量简单,大语句拆成小语句,减少锁时间;一条大语句可以堵死整个库。
  • 不用select *
  • OR改成IN。用OR的时间复杂度是N,用in的时间复杂度是logN。in的个数在200以内。
  • 不用函数和触发器,在应用程序中实现!!
  • 避免模糊查询 like "%xxxx"。会导致索引字典失效。
  • 少用JOIN,更要减少使用子查询。
  • 使用同类型比较: “123”和“123”比较, 123和123比较。
  • 尽量避免在where子句中使用 !=和<>操作符,因为会导致全表扫描,而不是使用索引。
  • 对于连续数值,使用between, 不要用in。SELECT id FROM t WHERE num BETWEEN 1 AND 5
  • 列表数据不要取全表数据,用limit分页查询,每页也不要太大。

其他优化方案:

  • 引擎的选择
  • 系统调优参数
  • 升级硬件
  • 缓存
  • 表分区
  • 对表进行垂直拆分
  • 水平拆分(非常复杂)

面试官问sql如何提高查询效率?(数据分析岗位)

原文地址:https://www.cnblogs.com/chentianwei/p/12154973.html