前言MySQL是一个关系型数据库管理系统。关系数据库将数据存储在不同的表中,而不是将所有数据放在一个大型仓库中,这样可以提高速度和灵活性。由于其体积小、速度快、总体拥有成本低,尤其是开源的特点,一般选择MySQL作为中小型网站开发的网站数据库。由于其社区版的优异性能,可以与PHP、Apache形成良好的开发环境。优化数据类型的常用技巧确定数据类型的优先级在为列选择数据类型时,第一步是确定合适的大类型:数字、字符串、时间等,下一步是选择具体的类型.很多MySQL数据类型可以存储同一类型的数据,但存储长度和范围不同,允许的精度不同,或者需要的物理空间(磁盘和内存空间)不同。同一大类型的不同子类型数据有时会有一些特殊的行为和属性。通常越小越好一般来说,您应该尝试使用可以正确存储数据的最小数据类型。较小的数据类型通常速度较快,因为它们占用较少的磁盘、内存和CPU缓存,并且需要较少的CPU周期来处理。但是请确保您不要低估需要存储的值的范围。简单就是好对简单数据类型的操作通常需要较少的CPU周期。例如,对整数进行操作比对字符的操作成本更低,因为字符集和排序规则(collat??ions)使字符比较比整数更复杂。尽量避免使用NULL许多表包含NULL(空值)列,即使应用程序不需要存储NULL,这是因为NULL是该列的默认属性。通常,最好将列指定为NOTNULL,除非您确实需要存储NULL值。如果查询包含NULLable列,MySQL将更难优化,因为NULLable列会使索引、索引统计和值比较变得更加复杂。NULLable列使用更多存储空间并且需要在MySQL中进行特殊处理。当为NULLable列建立索引时,每个索引记录都需要一个额外的字节。如果您计划在列上建立索引,则应避免将列设计为NULL。注意:例如:DATETIME和TIMESTAMP列可以存储相同类型的数据:时间和日期,精确到秒。但是TIMESTAMP只使用了DATETIME一半的存储空间,而且会根据时区变化,具有特殊的自动更新能力。另一方面,TIMESTAMP允许的时间范围要小得多,有时它的特殊能力可能会成为障碍。遵循数据库设计的三大范式***范式,保证每一列的原子性(强调的是列的原子性,即该列不能再拆分为其他列)。如果每一列(或每个属性)不再是最小数据单位(也称为最小原子单位),则满足***范式。例如:customer表(name,number,address,...)其中“address”列还可以细分为country,province,City,district等。第二范式是在第二范式的基础上更进一步***正常形式。目标是保证表中的每一列都与主键相关(一是表必须有主键;二是不包括在主键中的列必须完全依赖于主键,但不仅仅依赖于主键的部分)如果一个关系满足***范式,而除主键之外的其他列都依赖于主键,则满足第二范式。例如:订单表(订单号,商品号,订单日期,价格,...),“订单号”为主键,“商品号”与主键列没有直接关系,即“productnumber”列不依赖于主键列,应该删除。第三范式是在第二范式的基础上更进了一步。目标是保证每一列都与主键列直接相关,而不是间接相关(另外,非主键列必须直接依赖于主键,不能存在传递依赖)。如果一个关系满足第二范式,并且除主键外的其他列不依赖于主键列,则满足第三范式。为了理解第三范式,有必要根据阿姆斯特朗千米之一来定义传递依赖。假设A、B、C是关系R的三个属性,如果A->B和B->C,那么从这些函数依赖可以推导出A->C。上面说了,依赖A->C是传递依赖。比如:订单表(订单号,订单日期,用户号,用户名,...),乍一看表没有问题,符合第二范式。每列都与主键列“订单号”相关。仔细看会发现,“用户名”与“用户号”相关,“用户号”与“订单号”相关。通过传递依赖后,“用户名”也与“订单号”相关联。为了满足第三范式,要把“用户名”列去掉,放到user表中。总结归一化的优点:(1)归一化更新操作通常比非归一化更快(2)当数据归一化良好时,很少或没有重复数据,因此只需要修改较少的数据(3)归一化表通常是更小,占用内存更少,所以处理速度更快(4)冗余数据非常少,这意味着在检索列表时不需要distinct和groupby语句。Schema设计,当你查询的时候,你通常需要一个关联查询。schema设计的简单原则是避免过度设计,比如schema设计会导致复杂的查询,或者表设计有很多列;使用小而简单的合适的数据类型,除非真的是数据模型中有确切的需要,否则应该尽量避免使用NULL值,尽量使用相同的数据类型来存储类似的或相关值,特别是对于关联条件中使用的列;注意变长字符串,在Temporarytablesorsorting中可能悲观地按照最大长度分配内存。尽量使用整数标识列,避免使用mysql已经放弃的特性,比如指定浮点数的精度(可以用小数代替),或者整数的显示宽度。谨慎使用ENUM和SET,尽量避免使用;避免使用BIT;createhigh-performanceindex高性能索引策略Independentcolumns我们经常会看到一些使用索引不当的查询,或者导致MySQL无法使用现有的索引。如果查询中的列不是独立的,MySQL将不会使用索引。“独立列”意味着索引列不能是表达式的一部分,也不能是函数的参数。前缀索引和索引选择性有时需要索引很长的字符列,这会使索引变大变慢。一种策略是前面提到的模拟哈希索引。通常可以对开头的一些字符进行索引,这样可以大大节省索引空间,提高索引效率,但同时也降低了索引的选择性。(索引选择性是指唯一索引值与数据表中记录总数的比值)索引的选择性越高,查询效率越高。多列索引一个常见的错误是为每一列创建单独的索引,或者以错误的顺序创建索引。但实际上,在多列上建立独立的单列索引,在大多数情况下并不能提高MySQL的查询性能。5.0及之后的版本引入了“索引合并”策略,在一定程度上缓解了这个问题。(但没有完全解决)索引合并策略有时是一种优化的结果,但其实更多的时候是指表上的索引很糟糕。当服务器对多个索引进行交集运算时,意味着一个包含所有相关列的多列索引,而不是多个独立的单列索引当服务器需要对多个索引进行联合运算时,通常需要大量的用于算法缓存、排序和合并的CPU和内存资源。优化不会将这些计入“查询成本”,优化器只关心随机页面读取。这会让查询的代价“被低估”,以至于执行计划还不如直接全表扫描。选择合适的索引列顺序。正确的顺序取决于使用索引的查询,还需要考虑如何最好地满足排序和分组的需要。在多列B-TREE中,索引列的顺序是指索引按最左边的列在前,第二列在后,依此类推。关于如何构建索引列的顺序有一个经验法则:将最具选择性的列放在索引中的第一位。索引的优点a.通过创建唯一索引,可以保证数据库表中每一行数据的唯一性。b.它可以大大加快数据的检索速度,这是创建索引的主要原因。C。它可以加快表与表之间的连接,特别是在实现数据的参照完整性方面。d.当使用分组和排序子句进行数据检索时,还可以显着减少查询中分组和排序的时间。e.通过使用索引,可以在查询过程中使用优化隐藏器来提高系统的性能。索引的缺点A.创建和维护索引都需要时间,而且这个时间随着数据量的增加而增加。b.索引需要占用物理空间。除了数据表占用的数据空间外,每个索引还占用一定的物理空间。如果要建立聚簇索引,需要的空间就更大了。C。在对表中的数据进行增删改查时,索引也要动态维护,降低了数据维护的速度。备注:因为索引比较占内存,所以索引也需要慎重添加,需要对那些字段进行索引。mysql查询生命周期客户端向服务器发送查询;服务器先查询缓存,如果安装了缓存则直接返回结果;否则,进入下一步;服务器进行SQL解析和预处理,然后由优化器生成相应的执行计划;mysql根据优化器生成的执行计划调用存储引擎API执行查询;将查询结果返回给客户端;SHOWFULLPROCESSLIST可以查看当前状态;sleep:线程正在等待客户端发送新的请求;查询:线程正在执行查询或将结果发送给客户端;Locked:线程正在等待表锁;分析统计:线程正在收集存储引擎的统计信息,并产生查询的执行计划;Copingtotmptable:线程正在执行Query并将其结果复制到临时表;排序结果:线程正在对结果集进行排序;发送数据:线程可能在多个状态之间传递数据,或者正在生成结果集,或者向客户端发送数据;查询性能优化1、慢查询基础:优化数据访问低效查询分析方法:a.确认应用程序是否正在检索大量超出要求的数据。通常意味着访问的行太多,也可能访问的列太多。b.确认mysql服务器层是否正在分析比需要的大量数据行。查询效率低下的典型案例:a.查询不需要的记录b.多表关联时返回所有列c.始终获取所有列d。重复查询同一条数据衡量查询开销的三个指标:a.响应时间responseTime包括服务时间和排队时间;服务时间:指数据库处理查询所用的时间,排队时间:服务器因为等待某些资源(可能是IO、行锁等)而没有真正执行查询的时间;b.扫描的行数;C。返回行数越少的行访问速度越快,内存中的行比磁盘中的行快;行数少的在内存中查询,行数大的时候在磁盘上查询;重构查询方法a。一个复杂查询或多个简单查询;b.具有少量扫描行的查询);C。分解关联查询,优点:使缓存更高效;让单个查询减少锁竞争;在应用层做关联,便于拆分数据库,提高系统性能;减少冗余记录的查询;
