• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Mysql遇到的一些问题
 

Mysql遇到的一些问题

on

  • 868 views

mysql基础方面的分享 很基础很基础

mysql基础方面的分享 很基础很基础

Statistics

Views

Total Views
868
Views on SlideShare
868
Embed Views
0

Actions

Likes
2
Downloads
24
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Mysql遇到的一些问题 Mysql遇到的一些问题 Presentation Transcript

    • MySql遇到的一些问题
      王同超
      zbwangchao@163.om
    • 提纲
      性能—慢查询
      一些原则
      索引结构
      Myisam innodb引擎
      几个技巧、和认识
    • 性能相关
      程序
      数据库本身配置(很多比较复杂)
      前端页面(页面请求 css js):
      工具 :
      • YSlow
      • Page Speed
      • Mysqldumpslow
      • mysqlsla
    • Count(*) count(1) count(userid) 的认识误区
      意义不同
      Count(*) = count(0) 表的行总数,也不存在count(1)比count(*)性能更好的说法
      Count(userid): userid 非NULL字段总数
      本页备注有测试用例
    • Myisaminnodb
      Myisam ≈ sqlserver堆表
      史上最快(select insert 性能超好)(update delete 超烂),update 、delete:lock、更新索引
      表锁
      B-tree (depth:2-3)
      Page size 1K,很少关注这个数据
      只缓存索引=>(尽可能的使用覆盖索引)
      Innodb
      B+tree索引(自动hash)
      Page size:16K(很重要)
      事物
      行锁(mvcc多版本并发控制)
      高并发
      缓存数据+索引
    • B-tree
      B-Tree 特性
      关键字集合分布在整颗树中;
      任何一个关键字出现且只出现在一个结点中;
      搜索有可能在非叶子结点结束;
      其搜索性能等价于在关键字全集内做一次二分查找;
      自动层次控制;
      B-树
      是一种多路搜索树(并不是二叉的):
      1.定义任意非叶子结点最多只有M个儿子;且M>2;
      2.根结点的儿子数为[2, M];
      3.除根结点以外的非叶子结点的儿子数为[M/2, M];
      4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)
      5.非叶子结点的关键字个数=指向儿子的指针个数-1;
      6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];
      7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
      8.所有叶子结点位于同一层;
    • B+tree
      B+树是B-树的变体,也是一种多路搜索树:
      1.其定义基本与B-树同,除了:
      2.非叶子结点的子树指针与关键字个数相同;
      3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);
      4.为所有叶子结点增加一个链指针;(范围查询)
      5.所有关键字都在叶子结点出现;
      B+的特性:
      1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
      2.不可能在非叶子结点命中;
      3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
      4.更适合文件索引系统;
    • 总结
       B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;
       B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;
      =>保证节点的利用率
    • Myisam 存储结构
      Myisam的并发插入:concurrent_insert=[0,1,2]
    • Myisam
      高速select insert
      myisam 生来就是为了插入和查询设计的,天生的log工具
    • Myisam 索引结构
      能得到的东西:
      Myisam的索引是无差别的
      尽可能的使用覆盖索引,避免磁盘io
    • Innodb 数据结构
      数据按主键存放,构成一个b-tree
      主键使用自增int等,避免guid(节点分裂、合并)
    • Innodb 表文件
      每次io都会整页返回数据,再内存处理=>row越小越好=>大字段切分独立表=>
      现在的很多应用都放在nosql(豆瓣)
    • 聚集索引
    • 非聚集索引
    • Innodb
      安全(innodb double write,redo log, undo log)
      高可用
      高并发(<=行锁 mvcc)
      =>update
    • B-tree B+tree
      树的深度和广度是由数据量决定
      (log N)/log B to (log N)/log 2B ~~LogB N
      Btree 自动控制树的深度:2-3
      结论:
      分表不解决查询的性能问题
      百万、千万、亿、数据量的表查询性能相当
      不恰当的分区分表会造成很大的性能问题(多次io):单表(2-3),多表((2-3)*n)
    • Delete update insert的性能问题到底在哪里
      聚集索引树的重新组织
      很严重的问题,所以聚集索引一定不能guid不确定数据类型,这也可能是为什么sqlserver的自增列永远不能修改的问题,引起数据页数据迁移问题很严重
      Guid数据引起大量数据页‘迁移’(btree节点分裂、合并)
      引起索引树(btree)节点的合并、分裂
      通常并不是所有的操作会马上引起合并和分裂,索引缓存和节点的左旋和右旋(b+tree)
      也未必会马上引起io操作
    • No update
      hbase
      { "aaaaa" : {
      "A" : {
      "foo" : {
      15 : "y",
      4 : "m"
      },
      "bar" : {
      15 : "d", } },
      "B" : {
      "" : {
      6 : "w"
      3 : "o"
      1 : "w"} } }}
      SELECT * FROM ol_answerresult_tongchao WHERE userid = 520006 AND questionid = '714168c0-80bb-4377-930d-b6acbecaee08’ ORDER BY time_version DESC LIMIT 1
      SELECT * FROM ol_answerresult_tongchao WHERE userid = 520006 AND questionid = '714168c0-80bb-4377-930d-b6acbecaee08’ ORDER BY AnswerResultId DESC LIMIT 1
      可能的应用:日志,作答记录,
      版本信息:自增id,timestamp
    • 性能优化的方向
      需求和架构及业务实现优化:55%
      Query 语句的优化:30%
      数据库自身的优化:15%
      业务和数据库各占一半
    • 别人解决问题的一般步骤
      Memcached+MySQL
      M-S(Mysql主从读写分离)
      分表分库(程序复杂度高很多)高并发MySQL应用开始使用InnoDB引擎代替MyISAM
      Nosql(高读写、free schema )
    • 推荐的优化顺序
      google page speed 和yslow 分析页面
      地毯式sql优化,按照每个页面优化
      设计最初不需要严格设计索引等,快速的实现业务为主
      生产环境下监控和优化,持续优化
    • 分表 分区
      影响性能的几个点
      索引的深度(2-3)产生的io次数
      分区分表不当,产生更多的io
      索引的大小,innodb的页大小,16k,索引越小,速度越快(io扫描扇区少)
      数据行数的影响很小1亿 500万,都能保证深度3
      Iometer
      每个扇区可以存放512个字节
    • 分表解决了什么问题?
    • 书上说
    • Mysql 配置G点
      query_cache_size
      table_cache
      thread_cache_size
      tmp_table_size<=(Created_tmp_disk_tables / Created_tmp_table)
      open_files_limit<=(Open_files / open_files_limit * 100% <= 75%)
      2.myisam的G点
      query_cache
      key_buffer_size
      3. innodb 的G点
      innodb_buffer_pool_size
      innodb_flush_log_at_trx_commit
      innodb_log_buffer_size
      innodb_log_file_size
      innodb_flush_method
    • 硬盘的几个数据
      10000rpm
      15000rpm
      缩短硬盘的平均寻道时间和实际读写时间
      目前Fast ATA接口硬盘的最大外部传输率为16.6MB/s,而Ultra ATA接口的硬盘则达到33.3MB/s。
    • Iops
      IOPS值一般从几十到几百(大多在100-200区间)
      IOPS值现在主要作为SSD固态盘的一个重要参数指标,一般一个普通的SSD,都很容易达到几千,专业些的产品可以达到几万!
    • 硬盘的几个概念
      目前硬盘的平均寻道时间通常在8ms到12ms之间,而SCSI硬盘则应小于或等于8ms。
      平均访问时间=平均寻道时间+平均等待时间。
      目前硬盘的平均寻道时间通常在8ms到12ms之间,而SCSI硬盘则应小于或等于8ms。 硬盘的等待时间,又叫潜伏期(Latency),是指磁头已处于要访问的磁道,等待所要访问的扇区旋转至磁头下方的时间。平均等待时间为盘片旋转一周所需的时间的一半,一般应在4ms以下。
    • 传输速率
      传输速率(Data Transfer Rate) 硬盘的数据传输率是指硬盘读写数据的速度,单位为兆字节每秒(MB/s)。
      硬盘数据传输率又包括内部数据传输率和外部数据传输率。
      内部传输率(Internal Transfer Rate) 也称为持续传输率(Sustained Transfer Rate),它反映了硬盘缓冲区未用时的性能。内部传输率主要依赖于硬盘的旋转速度。
      外部传输率(External Transfer Rate)也称为突发数据传输率(Burst Data Transfer Rate)或接口传输率,它标称的是系统总线与硬盘缓冲区之间的数据传输率,外部数据传输率与硬盘接口类型和硬盘缓存的大小有关。
      目前Fast ATA接口硬盘的最大外部传输率为16.6MB/s,而Ultra ATA接口的硬盘则达到33.3MB/s。
    • 硬盘的性能
      转速
      平均寻道时间
      目前硬盘的平均寻道时间通常在 9ms到11ms之间,如迈拓的钻石7代系列平均寻道时间为9ms。
      数据传输速率(内部,外部),我们测试的一般是外部,带buffer,
      目前大多数家用硬盘的内部传输率在60MB/s~90MB/s,内部数据传输率才是系统真正的瓶颈(“最大内部数据传输率”比“最大外部传输速率”要小很多,所以不要迷恋“最大外部传输速率”,它只是个传说),
    • 硬盘&内存
      顺序访问内存数据也比随机访问快,内存250000 行100字节数据,内存比磁盘快2500倍,内存的顺序访问只比随机快10倍。
      =>加内存,增加随机io性能=》缓存命中率高
    • mysql执行查询的一般性过程
      1.客户端发送查询到服务器
      2.服务器检查查询缓存 (HASH SQL)
      =>所以书写的sql语句大小写要尽量统一
      3.服务器解析,预处理和优化查询,生成执行计划。
      4.执行引擎调用存储引擎API执行查询。
      5.服务器将结果发送到客户端。
    • 查询缓存
      Myisam将sql的查询结果缓存在内存
      Hash sql语句
      1.缓存未命中原因
      查询不可缓存 : 不确定函数。current_date(),now(),结果太大, Qcache_not_cached会记录两种无法缓存的查询数量。
      服务器以前从来没见过这个缓存。
      查询结果被缓存过,但是服务器把它移除。
      很多缓存失效。
      2.很多缓存未命中,但是不能缓存的查询很少。
      查询缓存未被激活。
      服务器看到了以前未见过的查询
      缓存失效。
    • 技巧一:数据分页
      一、特殊场合下
      如果每页有20条结果,那么应该查询limit 21行数据,只显示20条,如果结果中有21行,那么就会有下一页。
      二、比较通用
      1.大数量分页
      SELECT * FROM ol_answerlog ORDER BY AnswerLogId LIMIT 1000000,10
      SELECT * FROM ol_answerlog g INNER JOIN(
      SELECT AnswerLogId FROM ol_answerlog ORDER BY AnswerLogId LIMIT 1000000,10
      ) AS tt USING(AnswerLogId)
      2.别人的建议:only 1000条
    • 技巧二,简单优化
      避免子查询(临时表不支持索引)
      所以要让子查询创建的临时表尽可能的小。
      可以利用MYISAM对COUNT(*)的优化对已经有索引的一小部分做统计。
      SELECT COUNT(*) FROM WORD.CITY WHERE ID>5;
      优化为下面的语句
      SELECT (SELECT COUNT(*) FROM CITY) - COUNT(*) FROM CITY WHEREID<=5;
      这样的explain只扫描6行数据
      1.确保on 或using使用的列上有索引。
      通常只需要在联接中的第2个表上添加索引就可以。
      2.确保group by或order by只引用一个表中的列。这样可以使用索引。
      1.把一个复杂的查询分解为多个简单的查询。(mysql一般的服务器,每秒钟可以处理50 000个查询)
    • 启立说过一句
      很实在的话“把每个请求弄的都快了比什么都好”
      公务员最大的活跃用户100W
      nosql的不可靠要考虑清楚,
      长处一定是要结合分布式才优秀,
      实现成本越低,肯定问题越多
    • 技巧三:数据维护
      不要对一个大表进行delete update操作
      在新表中替代
      RENAME TABLE my_summary TO my_summary_old, my_summary_new TO my_summary;
      放在一个事物中,避免脏数据。
    • Insert delayed
      用户‘DELAYED‘
      立即返回,放入缓冲当中,无法使用LAST_ISNERT_ID()
      不是万金油,可配置、有限的insert队列
    • 优化数据访问的原则
      查询性能低下的最基本原因就是访问了太多数据。一些查询不可避免的要筛选大量的数据,但这并不常见。大部分性能欠佳的查询都可以用减少数据访问的方式进行修改。
      分析性能欠佳的查询,两个步骤:
      1.应用程序是否在获取超过需要的数据。这通常是访问了过多的行或列。
      2.mysql服务器是否分析了超过需要的行
      Userinfouserinfo = UserBO.GetUserList().First();
      。。。其他优化手段
    • 原则实例
      对于访问的数据行很大,而生成的结果中数据行很少
      1.使用覆盖索引,它存储了数据,所以存储引擎不会去扫描完整的行。
      2.更改架构,一个例子就是使用汇总表。
      3.重写复杂的查询,让mysql的优化器可以优化的执行。
    • 公务员优化的一些手段
      硬件加内存
      提高缓存命中率(30->40),减少io
      业务优化,减少请求,去掉不必要的sql语句
      (键富,本地缓存)
      慢查询优化:很多具体的例子不列举
    • 分享两个ppt
      百姓网
      51job
    • 表切分的一个实例
      大字段切分(text)
      小索引文件
      实例
      1: edu的 ol_question(100W >3G)
      很典型的一个设计问题
    • Buffer 策略
      定时 ,过期前更新,
      阀值75%,提前更新数据
    • 别人说的索引经验数据
      • 5个(3*5),非官方,经验值,不完全的
      • 扩展索引,非增加=>更多的覆盖索引
      • 尽量使用覆盖索引(不用扫描磁盘取数据)
      • 满足业务的基础上,越少越好(update 性能)
      • 查询性能取决与深度,非rows,基本都在2-3
      • 减少count()
      • 如何分表(业务隔离性好的字段)hash range index map
    • 基准测试工具
      Sysbench
      Mysqlsla
      Benchmark
      Lr
      http_load
    • 项目的现在&将来(DB方面)
      • 目前的使用经验基本能支撑相当一段时间访问
      • 需要解决的问题
      高可用HA
      M-M:hearbmeat mmm 高端存储
      M-S:LVS DNS
      热备份
      监控
      网络成本,有必要的时候项目内网网络升级千兆
    • END