`
student_lp
  • 浏览: 428586 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

    即使用正确的类型创建了表并加上了合适的索引,工作也没有结束,还需要维护表和索引来确保他们都正常工作。维护表有三个主要的目的:找到并修复损坏的表,维护准确的索引统计信息,减少碎片。

一、找到并修复损坏的表

    表损坏是很糟糕的事情。对于MySQL存储引擎,表损坏通常是系统崩溃导致的。其他引擎也会由于硬件问题、MySQL本身的缺陷或者操作系统的问题导致索引损坏。损坏的索引会导致查询返回错误的结果或者莫须有的主键冲突等问题,严重甚至还会导致数据库的崩溃。

    运行CHECK TABLE来检查是否发生了表损坏。check table通常能够找出大多数的表和索引的错误。可以使用repair table命令来修复损坏的表。(注意:有些存储引擎并不支持这两个命令)

    此外也可以使用一些存储引擎相关的离线工具,例如myisamchk;或者将数据导出一份,然后重新导入。不过,如果损坏的是系统区域,或者是表的“行数据”区域,而不是索引,那么上面的办法就没有用了。这种情况下,可以从备份中恢复表,或者尝试从损坏的数据文件中尽可能的恢复数据

    如果InnoDB引擎的表出现了损坏,那么一定是发生了严重的错误,需要立即调整调查一下原因。InnoDB一般不会出现损坏。InnoDB的设计保证了它并不容易损坏。如果发生损坏,一般要么是数据库的硬件问题例如内存或者磁盘问题,那么是由于数据库管理员的错误例如在MySQL外部操作了数据文件,抑或是InnoDB本身的缺陷(不太可能)。常见的类似错误通常是由于尝试使用rsync备份InnoDB导致的。不存在什么查询能够让InnoDB表损坏,也不用担心暗处有陷阱。如果某条查询导致InnoDB数据的损坏,那一定是遇到bug,而不是查询的问题。

    如果遇到数据损坏,最重要的是找出是什么导致了损坏,而不只是简单的修复,否则很有可能会不断的损坏。可以通过设置innodb_force_recovery参数进入InnoDB的强制恢复模式来修复数据。

二、更新索引统计信息

    MySQL的查询优化器通过两个API来了解存储引擎的索引值的分布信息,已决定如果使用索引。第一个API是records_in_range(),通过向存储引擎传入两个边界值获取在这个范围大概有多少记录。对于某些存储引擎,该接口返回精确值,例如MyISAM;但对于另一些存储引擎则是一个估算值,例如InnoDB。第二个API是info(),该接口返回各种类型的数据,包括索引的基数。

    如果存储引擎向优化器提供的扫描函数信息是不准确的数据,或者执行计划本身太复杂以致无法准确的获取各个阶段的匹配的行数,那么优化器会使用索引统计信息来估算扫描行数。MySQL优化器使用的是基于成本的模型,而衡量成本的主要指标就是一个查询需要扫描多少行。如果表没有统计信息,或者统计信息不准确,优化器就很可能做出错误的决定。可以通过运行analyze table来重新生成统计信息解决这个问题。

    每种存储引擎实现索引统计信息的方式不同,所以需要进行analyze table的频率也因不同的引擎而不同,每次运行的成本也不同:

  • memory引擎根本不存储索引统计信息;
  • MyISAM将索引统计信息存储在磁盘中,analyze table需要进行一次全索引扫描来计算索引基数。在整个过程中需要锁表;
  • 直到MySQL5.5版本,InnoDB也不在磁盘存储索引统计信息,而是通过随机的索引访问进行评估并将其存储在内存中。

    可以使用show index from命令来查看索引的基数。这个命令输出了很多关于索引的信息,这里特别提及的是索引列的基数(Cardinality),其显示了存储引擎估算索引列有多少不同的取值。需要注意如果服务器上的库表非常多,则从这里获取元数据的速度可能会非常慢,而且会给MySQL带来额外的压力。

    InnoDB引擎通过抽样的方式来计算统计信息,首先随机的读取少量的索引页面,然后依次为样本计算索引的统计信息。在老的InnoDB版本中,样本页面数是8,新版本的InnoDB可以通过参数innodb_stats_sample_pages来设置本页的数量。设置更大的值,理论上来说可以帮助生成更准确的索引信息,特别对于某些超大的数据表来说,但具体设置多大适合依赖于具体的环境。

    InnoDB会在表首次打开,或者执行analyze table,抑或表的大小发生非常大的变化的时候计算索引的统计信息。InnoDB在打开某些infomation_schema表,或者使用show table status和show index,抑或在MySQL客户端开启自动补全功能的时候都会触发索引统计信息的更新。如果服务器上有大量的数据,这可能是一个很严重的问题,尤其是当I/O比较慢的时候。客户端或者监控程序触发索引信息采样更新可能会导致大量的锁,并给服务器带来很多的额外压力,这会让客户因为启动时间漫长而沮丧。只要show index查看索引统计信息,就一定会触发统计信息的更新。可以关闭innodb_stats_on_metadata参数来避免上面提到的问题。

    一旦关闭索引统计信息的自动更新,那么就需要周期性的使用analyze table来动手更新,否则,索引统计信息就会永久不变。如果数据分布发生很大的变化,可能会出现一些很糟糕的执行计划。

三、减少索引和数据的碎片

    b-tree索引可能会碎片化,这会降低查询的效率。碎片化的索引可能会以很差或者无序的方式存储在磁盘上。根据设计,b-tree需要随机磁盘访问才能定位到叶子页,所以随机访问是不可避免的。然而,如果叶子页在物理分布上是顺序紧密的,那么查询的性能会更好。否则,对于范围查询、索引覆盖扫描等操作来说,速度可能会降低很多倍,对于索引覆盖扫描这一点更加明显。

    表的数据存储也可能碎片化。然而,数据存储的碎片化比索引更加复杂。有三种类型的数据碎片:

  • 碎片化---这种碎片指的是数据行被存储为多个片段中。即使查询也从索引中访问一行记录,碎片也会导致性能下降。
  • 行间碎片---行间碎片是指逻辑上顺序的页,或者行在磁盘上不是顺序存储的。行间碎片对诸如全表扫描和聚簇索引扫描之类的操作有很大的影响,因为这些操作原本能够从磁盘上顺序存储的数据中获益。
  • 剩余空间碎片---剩余空间碎片是指数据页中有大量的空余空间。这会导致服务器读取大量不需要的数据,从而造成浪费。

    对于MyISAM表,这三类碎片都可能发生。但InnoDB不会出现短小的行碎片;InnoDB会移动短小的行并重写到一个碎片中。

    对于通过执行optimize table或者导出再倒入的方式重新整理数据。这对多数存储引擎都是有效的。对于一些储存引擎如MyISAM,可以通过排序算法重新索引的方式来消除碎片。对于那些不支持optimize table的存储引擎,可以通过一个不做任何操作的alter table操作来重新建表,如:alter table tablename engine=<engine>。对于开启了expand_fast_index_creation参数的Percona Server,按这种方式重建表,则会同时消除表和索引的碎片化。但对于标准版的MySQL则只会消除表的碎片化。可以先删除所有索引,然后重建表,最后重建索引的方式模拟percona Server的这个功能。

 

分享到:
评论

相关推荐

    数据库维护计划和索引重建

    使用SQL管理,自建数据库维护计划和索引重建,新建一个维护计划,3. 输入执行维护计划的名称,选择“整个计划统筹安排或无计划”,点击【更改】按钮,对作业计划属性进行修改,根据实际情况,选择计划类型、执行频率...

    Oracle数据库索引的维护

    Oracle数据库索引的维护

    关于SQL Server中索引使用及维护简介

    每张表只能建一个聚簇索引,并且建聚簇索引需要至少相当该表 120%的附加空间,以存放该表的副本和索引中间页。 SQL Server缺省情况下建立的索引是非聚簇索引,由于非聚簇索引不重新组织表中的数据,而是对每一行...

    索引维护方法

    Microsoft SQL Server 索引维护,维护源代码, Perfmon性能查看选择,留在自己用。

    Oracle数据库中索引的维护

    Oracle数据库中索引的维护,介绍关于索引的维护 oracle 版本 8.0

    高性能MySQL(第3版).part2

    5.5维护索引和表187 5.5.1找到并修复损坏的表187 5.5.2更新索引统计信息188 5.5.3减少索引和数据的碎片190 5.6总结192 第6章查询性能优化195 6.1为什么查询速度会慢195 6.2慢查询基础:优化数据访问196 ...

    数据库原理实践报告视图、索引的建立和维护;

    数据库、数据表的创建视图、索引的建立和维护; SQL定义、查询、更新语句

    MySQL数据库:索引概述.pptx

    索引一旦创建,将由数据库自动管理和维护。在编写SQL查询语句时,具有索引的表与不具有索引的表没有任何区别,索引只是提供一种快速访问指定记录的方法。 索引概述 索引的作用 索引是一种提高查找速度的机制 索引...

    Oracle表分区和索引分区

    Oracle表分区和索引分区 分区概述 为了简化数据库大表的管理,例如在数据仓库中一般都是TB级的数量级.ORACLE8以后推出了分区选项.分区将表分离在若于不同的表空间上,用分而治之的方法来支撑元限膨胀的大表,组...

    ORACLE分区与索引

    对orcle大数据的查询的...然后在分区内部去查找数据,一个分区一般保证四十多万条数据就比较正常了,但是分区表并非乱建立,而其维护性也相对较为复杂一点,而索引的创建也是有点讲究的,这些以下尽量阐述详细即可。

    SQL Server 2005 中的分区表和索引

    SQL Server 2005 中基于表的分区功能为简化分区表的创建和维护过程提供了灵活性和更好的性能。追溯从逻辑分区表和手动分区表的功能到最新分区功能的发展历程,探索为什么、何时以及如何使用 SQL Server 2005 设计、...

    ORACLE重建索引总结

    3 、rebuild online 时系统会产生一个 SYS_JOURNAL_xxx 的 IOT 类型的系统临时日志表 , 所有 rebuild online 时索引的变化都记录在这个表中 , 当新的索引创建完成后 , 把这个表的记录维护到新的索引中去 , 然后 ...

    索引创建维护

    Oracle索引回顾 B*索引 位图索引 函数索引 逆键索引 索引的维护

    论文研究-索引及分裂大表技术在油井数据维护系统的应用 .pdf

    索引及分裂大表技术在油井数据维护系统的应用,左杰,王雄,本文通过在油井数据维护系统的开发应用过程中,对数据库查询进行优化的研究和实践,介绍了索引技术[1]和分裂大表技术[2]和这两个技

    pgsql-bloat-estimation:用于测量 PostgreSQL 索引和表中统计膨胀的查询

    pgsql-膨胀-估计用于测量 PostgreSQL 的 btree 索引和表中统计膨胀的查询。 应考虑三种不同类型的未使用空间: 对齐填充:根据类型,PostgreSQL 会向您的字段添加一些填充以在行中正确对齐它们。 这与一些 CPU 操作...

    69 更新数据的时候,自动维护的聚簇索引到底是什么?l.pdf

    69 更新数据的时候,自动维护的聚簇索引到底是什么?l.pdf

    安卓A-Z字母排序索引相关-模仿微信联系人的字母索引ListView高拓展高维护。.zip

    模仿微信联系人的字母索引ListView,高拓展,高维护。.zip,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。

    关于Oracle数据库中索引的维护

    关于Oracle数据库中索引的一些维护经验谈

    Elasticsearch之索引维护

    Elasticsearch存储数据之前需要先创建索引,类似于结构型数据库建库建表,创建索引时定义了每个字段的索引方式和数据类型。  常用API: 1、查看指定索引信息: GET http://$user:$passwd@$host:$port/$index 2:...

Global site tag (gtag.js) - Google Analytics