设为首页 收藏本站
查看: 787|回复: 0

[经验分享] 数据库 之 Mysql优化的问题

[复制链接]

尚未签到

发表于 2018-10-2 10:59:28 | 显示全部楼层 |阅读模式
  1  概述
  数据库优化的方法有四个:
  索引策略,通过explain来判断索引的有效性,移除多余索引,保留有效的索引
  单机缓存,mysql内键的缓存
  旁挂缓存,如使用redis或者memcached,由程序自行决定是否将结果进行缓存
  修改相关参数,提升mysql服务器的性能
  本文主要介绍mysql的单机缓存以及相关参数的介绍
  2  单机缓存
  mysql的内键缓存机制,query  cache(查询缓存),mysql缓存功能是自带的,但是需要启用,为了足够高效命中,mysql在内存中开辟缓存空间,缓存中的数据是kv值,kv值也是缓存提高效率的原因之一。
  这里的问题是要把什么当做键,键是hash值,所以需要将查询结果做hash运算。Mysql的缓存是非预先分配的,可能会造成碎片,降低效率
  为了提高缓存命中率,要使得程序员使用同一种分隔来写语句,如都是用大写,或者某些关键字都是小写,原因是mysql会将查询语句做hash运算,大小写不一样的话,hash值就不同。如果hash值不同,将不能被命中。通常是把关键词大小。
  mysql的查询缓存是单机的,缓存是放在本地主机上。考虑到缓存命中率,在前端调度的时候,可以基于语句做路由,同一语句调度到同一主机上。但是proxysql没有这种调度能力,haproxy可以实现七层协议调度,但是mysql不支持七层协议,mysql是列表语句,因此不能通过haproxy来做这种调度
  查询缓存:
  缓存:k/v
  key:查询语句的hash值
  value:查询语句的执行结果
  如何判断缓存是否命中:
  通过查询语句的哈希值判断:哈希值考虑的因素包括
  查询本身、要查询数据库、客户端使用的协议版本、...
  SELECT Name FROM students WHERE StuID=3;
  Select Name From students where StuID=3;
  哪些查询可能不会被缓存?如下添加不变缓存
  1 查询语句中包含UDF(User-Defined Functions)
  2 存储函数
  3 用户自定义变量
  4 临时表
  5 mysql系统表或者是包含列级别权限的查询
  6 有着不确定结果值的函数(now());
  7 select 语句,如果已经启用按需缓存,那么在select 语句中,[SQL_CACHE | SQL_NO_CACHE]这两个选项则明确表明该语句需要缓存或者不缓存,如明确使用sql_no_cache则不缓存
  查看缓存相关的选项
  MariaDB [(none)]> show global variables like '%cache%';
  查询缓存相关的服务器变量介绍:
  query_cache_limit:能够缓存的最大查询结果;(单语句结果集大小上限)
  有着较大结果集的语句,显式使用SQL_NO_CACHE,以避免先缓存再移出;默认是1M
  query_cache_min_res_unit:内存块的最小分配单位;缓存过小的查询结果集会浪费内存空间;
  较小的值会减少空间浪费,但会导致更频繁地内存分配及回收操作;
  较大值的会带来空间浪费;
  query_cache_size:查询缓存空间的总共可用的大小;单位是字节,必须是1024的整数倍;0表示没有启用 。这个数字建议不要随便调整,因为每次调整这个值,之前的缓存项都会被删除,缓存需要重新生成
  如设置为64M,命令如下
  MariaDB [(none)]> set @@global.query_cache_size=67108864;
  query_cache_strip_comments
  query_cache_type:缓存功能启用与否;
  ON:启用;能缓存的数据就缓存,处理以上提到的7类不能缓存的查询
  OFF:禁用;
  DEMAND:按需缓存,仅缓存SELECT语句中带SQL_CACHE的查询结果;如果确定结果大小比缓存空间大,明确不缓存,即no_cache。
  query_cache_wlock_invalidate:如果某表被其它连接锁定,是否仍然可以从查询缓存中返回查询结果;默认为OFF,表示可以;ON则表示不可以;默认是OFF(允许的,双重否定invalidate OFF所以是启用的,读多写少的环境,缓存基本是有效的)
  查看状态变量:计数器,查询名字或者插入的次数。
  mysql> SHOW GLOBAL STATUS LIKE 'Qcache%';
  +-------------------------+----------+
  | Variable_name           | Value    |
  +-------------------------+----------+
  | Qcache_free_blocks      | 1 空闲的块数       |
  | Qcache_free_memory      | 16759688 |查询缓存尚且剩余的空间
  | Qcache_hits             | 0  表示命中缓存的次数    |
  | Qcache_inserts          | 0  表示查询插入的次数    |
  | Qcache_lowmem_prunes    | 0  这个值很大,说明缓存空间太小      |
  | Qcache_not_cached       | 0   本来要放入缓存空间但是实际没有被缓存的数量     |
  | Qcache_queries_in_cache | 0   在缓存系统中查询的个数     |
  | Qcache_total_blocks     | 1    查询总的块数    |
  +-------------------------+----------+
  评估select缓存命中率公式如下:
  Qcache_hits/Com_select
  当读写操作差不多的时候,建议关闭该功能,但是如果是大量查询,即读多写少的环境中,建议启用缓存
  注意,第一次查询时生成缓存,接下去的查询才会命中缓存
  查看Com_select的总数
  MariaDB [sunny]> show global status like 'Com%select%';
  3  修改相关参数
  Innodb存储引擎相关的参数查看命令如下
  MariaDB [sunny]> show global variables like 'innodb%';
  一般不建议使用默认参数,
  优化相关参数,一般以下的参数不使用默认数值运行,而是要根据实际情况调整后才能使用服务,相关参数介绍如下
  innodb_buffer_pool_size这个参数的相关解释如下:
  innodb的缓存池的大小,通常用来缓存索引,数据,插入数据时的缓冲区。innodb_buffer_pool_size这个参数一般要根据实际情况调大,不支持动态修改,需要修改配置文件,默认是128M,这个值一般要调大,提高性能的优化,这个是占用内存空间,这个根据服务器是专用或者组合使用的,来确定这个数值调整的大小。
  如果innodb引擎为主的主机,建议innodb_buffer_pool_size设置40%~60%的内存空间。
  如果msyql是专用主机,内存空间为32G以上,innodb_buffer_pool_size一般建议设置为70--80%的内存空间。这个值对mysql性能提升很有帮助。但是不能设置太大,如剩余的内存空间不够系统正常运转,可能会带来更多的问题,所以这个值要适当设置。
  如果数据集本身较小,可以根据数据变化幅度及规划的在线时长来设定合理的innodb_buffer_pool_size值,如比预估的目标值略大。
  5.7版本后innodb_buffer_pool_size可以动态调整,但是,建议将innodb_buffer_pool_size写入配置文件中,而且建议不要在系统繁忙时调整该值
  修改配置如下
  [root@node71 ~]#vim /etc/my.cnf.d/server.cnf
  [server]
  innodb_buffer_pool_size = 512M
  然后重启mysql服务后生效
  innodb_buffer_pool_instances:buffer_pool的区段(实例)数量, 表示把内存空间大小切割成几个空间字段,锁定的单位会变小,可以提高mysql运行效率,但是数量建议不要太多
  innodb_log_files_in_group : 一组的日志文件数量,至少两个
  innodb_log_file_size:日志文件大小,不能太大,默认是5M;根据实际情况来调整。建议调大,一般可以设定为50--100M
  innodb_flush_logs_at_trx_commit:事务提交刷写磁盘的设置参数,值为0 1 2
  0:log_buffer(内存中)每秒1次同步到log_file中,且同时会进行log file 到data file的同步操作,0最多丢失1s的事务
  1:每次提交时,log buffer同步到log file,,同时进行log file 到data file的同步操作,1最多丢失1次事务
  2:  每次提交时,log buffer同步到log file,,但是不会同时进行log file 到data file的同步操作,由mysql的线程自行决定什么时候进行刷新数据。2的性能最高,如果事务的安全性不是很大,建议设置为2
  建议:关闭autocommit,而后将此值innodb_flush_logs_at_trx_commit设置为1或2;
  innodb_file_per_table:innodb的诸多高级特性都依赖此参数,建议开启
  innodb_file_io_threads:文件读写的io线程数,如果CPU核心够多,建议调大,默认是4。这个值是要根据并发量和CPU核心数适量调整
  innodb_open_files:innodb可打开的文件数量上限,按需调整此值
  innodb_flush_method:innodb刷写磁盘的方式
  innodb_thread_concurrency:innodb的线程并发数,即内核级可以同时运行的线程数,一般是CPU核心数量*2
  skip_name_resolve:忽略主机名称解析,网络优化相关,禁止调用外部dns进行名称解析
  max_connections:最大并发连接数


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-607478-1-1.html 上篇帖子: mysql数据库权限 下篇帖子: 源码编译安装mysql-5.7.14
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表