mysql优化

目录

1、优化的目的:

2、优化的方法

(1)查询语句相关的优化:

(2)表字段设计建议:

(3)创建索引的原则:

(4)索引失效的场景:


1、优化的目的:

提升用户体验,提升程序执行性能;

2、优化的方法

(1)查询语句相关的优化:

  1. 只查询需要的列:不要使用SELECT *,尤其是当表有很多列而你只需要少数几列时。
  2. 避免在WHERE子句中对列进行函数操作:这会使索引失效。
  3. 使用表连接(JOINs)代替子查询:在可能的情况下,尽量使用JOINs来替代子查询,因为JOINs通常更有效率。

(2)表字段设计建议:

  • 字段长度设计;满足实际的业务需求即可(一般输入框都会字符长度设计),字段名一般小于12字符;
  • mysql 表字段不要超过50;超过-----》垂直分表
  • 使用合适的数据类型,bit ,char ,varchar ;
  • 尽量非空或者给定默认值,空存在导致索引存在失效的可能
  • 字段类型要一致,相同的一个字段属性,假如user_id是个bigint类型,在另一个表就不能varchar类型
  • 不得使用外键级联,外键级联关系在应用层解决; 性能问题
  • 单表数据量达到500W条或者存储超过2G,考虑分库分表的情况;一般预估三年左右的业务情况;大约200W 单表出现一定的性能问题;
  • 财务系统相关小数存储可以使用decimal字段;禁止使用 float ,double 字段属性;
  • 严格意义上,业务系统的数据必须包含逻辑删除属性---所有数据物理存储,不允许删除;
  • 大字段表的垂直拆解
    • 常见于描述字段,不常用的信息,但是很占行的空间,如果在列表查询的时候,影响性能;建议拆分
    • 业务属性本来就很多;此时按照业务的关联属性(热点查询条件),进行垂直拆分进行表设计,表字段不一致
  • 业务字段的水平拆解
    • 种表的字段属性一致;只是通过业务进行了动态表名切换;那么需要定的就是表名的生成规则
    • 按照年份等时间维度,按照业务区分规则确定表明;

(3)创建索引的原则:

  • 选择唯一性索引
  • 唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话,可能存在同名现象,从而降低查询速度。
  • 为经常需要排序、分组和联合操作的字段建立索引。经常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作会浪费很多时间。如果为其建立索引,可以有效地避免排序操作。
  • 为常作为查询条件的字段建立索引。如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,为这样的字段建立索引,可以提高整个表的查询速度。
  • 限制索引的数目;一般5个左右索引的数目不是越多越好。每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。
  • 尽量使用数据量少的索引。如果索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索需要的时间肯定要比对CHAR(10)类型的字段需要的时间要多。
  • 尽量使用前缀来索引。如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度。
  • 删除不再使用或者很少使用的索引。表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。[数据库]管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。
  • 最左前缀匹配原则,非常重要的原则。mysql会一直向右匹配直到遇到范围查询(c> 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
  • =和in可以乱序。比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
  • 尽量选择区分度高的列作为索引。区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在[大数据]面前区分度就 是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条 记录
  • 索引列不能参与计算,保持列“干净”。比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本 太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);
  • 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可

(4)索引失效的场景:

  1. 查询条件包含or,可能导致索引失效
  2. 如果字段类型是字符串,where时一定用引号括起来,否则索引失效
  3. like条件中前面带%
  4. 联合索引,查询时的条件列不是联合索引中的第一个列,索引失效。
  5. 在索引列上使用mysql的内置函数,列运算(如,+、-、*、/),索引失效。
  6. 字符串不加引号,出现隐式的类型转化
  7. 负向查询:索引字段上使用(!= 或者 < >,not in,not like)时,可能会导致索引失效。
  8. 索引字段上使用 is not null,可能导致索引失效。
  9. 左连接查询或者右连接查询查询关联的字段编码格式不一样,可能导致索引失效。
  10. mysql 估计使用全表扫描要比使用索引快,则不使用索引

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

越过难题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值