mysql 优化 及 安全
Laiyong Wang Lv5

结合网络上的知识点及实际项目经验,写点 mysql(innodb) 优化,主要从代码优化、 sql 优化及数据库优化考虑,服务器,集群,网络啥的,交给运维头疼去

优化

手段 : 数据库字段冗余,增添索引、优化sql、分库分表

老项目/老代码

能跑且跑的快那就别动它,若是跑的慢

  • 代码逻辑太复杂,跑的慢
    能忍就忍,不能忍的话,代码重构+服务器升级完事
  • sql 查询太慢
    1、配置
    1
    2
    3
    4
    5
    6
    //mysql.ini里
    -log-slow-queries = wanglaiyong.log
    //msql cli里
    mysql > set global slow_query_log=ON;//开启慢查询
    mysql > set global long_query_time = 3;//慢查询的 sql 标准,默认单位:秒
    mysql > set global long_queries_not_using_indexes=ON;//未使用索引的查询也写入慢查询日志
    2、sql 优化
    经过第一步配置,项目运行一段时间,看是哪些 sql 执行较慢并用 explain 查看原因
    ps:explain可以模拟优化器执行SQL查询语句,所以用来分析sql慢查询语句
    explain 有很多分析,但实际项目中,只要其使用到索引且扫描行数较少就行了(还有别的乱七八糟的一大堆分析字段,太麻烦了,基本不看),若是未使用索引,那就根据业务场景加索引,扫描行数多,那就看是否使用到索引且使用的是否合理
新项目/新模块/新增代码
  • 代码优化思路
    1、事务别开太长(提高并发,减少死锁)
    2、批量操作,别同一事物,循环下,一次循环一次事务操作一次数据库(减少锁定时间,提高并发)
    3、不同业务场景,处理多个关联表的顺序尽量相同,避免死锁(该死还是得死,看缘分了)
    4、尽量以更少次的查询查出更多想要的数据,io 其实很消耗资源(数据库的连接与断开很消耗资源)

  • sql 优化思路
    1、避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描
    2、Where 子句替换 HAVING 子句 因为 HAVING 只会在检索出所有记录之后才对结果集进行过滤
    3、针对业务创建合理的索引,但是写 sql 要使用且使用正确
    4、尽量不要连表写非常长的sql,可用多个短 sql 来实现一句长 sql 要实现的功能(这点与尽量减少查询次数有点冲突,其实有连接池复用,不会有太多明显的多次连接开销,而且数据库有缓存,短 sql 查询,多种场景都可复用)

  • 数据库方面
    1、范式优化: 比如消除冗余,为了节省空间
    2、逆范式优化:比如适当加冗余等,为的是减少连表查询
    3、拆分表:拆分又分垂直拆分和水平拆分,主要是表的数据量太大,影响到查询(垂直拆分是把不同的表拆到不同的数据库中,而水平拆分是把同一个表拆到不同的数据库中)

    安全(SQL注入)

    sql注入只对sql语句的准备(编译)过程有破坏作用
    1、sql 预编译可以完美解决sql注入
    2、对用户的提交的内容进行过滤,主要是字符串和特殊字符(可以根据业务来写不同的过滤方法)
    3、orm(对象关系映射) 使用优秀的orm,也可以解决大部分 sql 注入

实际开发中,需要对用户输入的内容进行过滤,例如 laravel 里的 request 类,实际执行的时候在使用 orm ,这样基本可以杜绝 sql 注入。 orm 都无法避免的 sql 注入,一个小小程序员别研究了,数据组又不是白拿工资的

 Comments