zoukankan      html  css  js  c++  java
  • 【面试攻略】msyql数据库优化

    【msyql数据库】
    常用存储引擎的适用环境。
    MyISAM:默认的 MySQL 插件式存储引擎。如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存 储引擎是非常适合的。MyISAM 是在 Web、数据仓储和其他应用环境下最常使用的存储引擎 之一。
    InnoDB:用于事务处理应用程序,支持外键。如果应用对事务的完整性有比较高的 要求,在并发条件下要求数据的一致性,数据操作除了插入和查询以外,还包括很多的更新、 删除操作,那么 InnoDB 存储引擎应该是比较合适的选择。InnoDB 存储引擎除了有效地降低 由于删除和更新导致的锁定,还可以确保事务的完整提交(Commit)和回滚(Rollback), 对于类似计费系统或者财务系统等对数据准确性要求比较高的系统,InnoDB 都是合适的选 择。
    MEMORY:将所有数据保存在 RAM 中,在需要快速定位记录和其他类似数据的环境 下,可提供极快的访问。MEMORY 的缺陷是对表的大小有限制,太大的表无法 CACHE 在内 存中,其次是要确保表的数据可以恢复,数据库异常终止后表中的数据是可以恢复的。 MEMORY 表通常用于更新不太频繁的小表,用以快速得到访问结果。
    MERGE:    用于将一系列等同的 MyISAM 表以逻辑方式组合在一起,并作为一个对象 引用它们。MERGE 表的优点在于可以突破对单个 MyISAM 表大小的限制,并且通过将不同 的表分布在多个磁盘上,可以有效地改善 MERGE 表的访问效率。这对于诸如数据仓储等 VLDB 环境十分适合。

    MyISAM和InnoDB最主要的差别就是Innodb支持事务处理与外键和行级锁。而MyISAM不支持.所以MyISAM往往就容易被人认为只适合在小项目中使用。
    一般游戏服务器数据库都选择InnoDB,因为更新很频繁,还需要用事务,有的功能还会用外键.

    【Innodb 四种行格式对比】
    COMPACT 行格式:    如果一个表有很多blob列,就会导致B-tree索引节点太满,存储的行数太少,使得整个索引的效率就大大降低了。
    DYNAMIC    行格式:    和compact格式的存储特性是一样的,不一样的是它增强了对于较长变长列的存储能力及支持更大的索引前缀。
    COMPRESSED行格式:和DYNAMIC存储特性一样,同时提供了表和索引数据的压缩处理。
    REDUNDANT 行格式:REDUNDANT兼容MySQL的旧版本。

    如果你的表有很多的blob字段请选择COMPRESSED行格式,否则就会出现下面的报错
    Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
     
    【导致问题的原因】
    总结了下原因是因为mysql-innodb是按照page存储数据的,每个page max size是16k,然后每个page两行数据,所以每行最大8k数据。如果你的字段是blob之类的话,会存储在page之外的溢出区里。
    但是innodb默认的approach(羚羊)存储格式会把每个blob字段的前864个字节存储在page里,所以你的blob超过一定数量的话,单行大小就会超过8k,所以就报错了
    【解决思路】
    解决方式是使用innodb的Barracuda(梭鱼) 存储格式
    这种格式对blob字段的处理方式是在page里头只存储一个20byte大小的指针,其它全存在溢出区,所以你轻易超不了8k
    【详细步骤】
    1. 打开mysql的配置my.ini。在innodb配置出添加:innodb_file_per_table=1
    大概的意思就是打开mysql每张表都是独立存储空间的开关
    2. 然后命令检查下上述开关是否打开。
    show variables like '%per_table%';
    3. 设置mysql全局变量:innodb_file_format = Barracuda(梭鱼)
    命令:set GLOBAL innodb_file_format = 'Barracuda';
    然后检查下是否设置好了:
    命令:show GLOBAL VARIABLES LIKE '%file_format%';
    4. 设置对应表的属性:ROW_FORMAT=COMPRESSED
    然后检查下标的属性是否是你设置的:COMPRESSED

    【MySQL/Oracle数据库优化】
    1、选取最适用的字段属性
    MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。
    例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了。同样的,如果可以的话,我们应该使用MEDIUMINT而不是BIGIN来定义整型字段。
    另外一个提高效率的方法是在可能的情况下,应该尽量把字段设置为NOTNULL,这样在将来执行查询的时候,数据库不用去比较NULL值。
    对于某些文本字段,例如“省份”或者“性别”,我们可以将它们定义为ENUM类型。因为在MySQL中,ENUM类型被当作数值型数据来处理,而数值型数据被处理起来的速度要比文本类型快得多。这样,我们又可以提高数据库的性能。

    2.使用索引
    索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快得多的速度检索特定的行,尤其是在查询语句当中包含有MAX(),MIN()和ORDERBY这些命令的时候,性能提高更为明显。
    一般说来,索引应建立在那些将用于JOIN,WHERE判断和ORDERBY排序的字段上。尽量不要对数据库中某个含有大量重复的值的字段建立索引。对于一个ENUM类型的字段来说,出现大量重复值是很有可能的情况

    3.优化的查询语句
    首先,最好是在相同类型的字段间进行比较的操作。
    其次,在建有索引的字段上尽量不要使用函数进行操作。
    第三,在搜索字符型字段时,我们有时会使用LIKE关键字和通配符,这种做法虽然简单,但却也是以牺牲系统性能为代价的。
    最后,应该注意避免在查询中让MySQL进行自动类型转换,因为转换过程也会使索引变得不起作用。
    4.建表注意事项
    只要列中包含有NULL值都将不会被包含在索引中,所以我们在数据库设计时不要让字段的默认值为NULL。

    【sql优化实例】
    1.这将导致索引失效而进行全表扫描,因此我们可以改成
    select * from users where YEAR(adddate)<2007;       #错误的用法
    select * from users where adddate<‘2007-01-01';        #正确的用法

    2.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描,如:
    select id from t where num=10 or Name = 'admin'                                    #错误的用法
    select id from t where num=10 union all select id from t where Name = 'admin'    #正确的用法    

    3.对于连续的数值,能用 between 就不要用 in 了:
    select id from t where num in(1,2,3)            #错误的用法
    select id from t where num between 1 and 3        #正确的用法    

    4.可以改为强制查询使用索引:
    select id from t where num = @num                        #错误的用法
    select id from t with(index(索引名)) where num = @num   #正确的用法    

    5.
    应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
    select id from t where num/2 = 100        #错误的用法
    select id from t where num = 100*2        #正确的用法    


    原文:https://blog.csdn.net/baidu_37107022/article/details/77460464

    我的总结
    1.尽量根据实际长度定CHAR长度,别浪费空间
    2.尽量用整形别用中文
    3.使用索引,避免过度索引。
    4.使用sql的时候避免一些使索引失效的用法
    5.尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
    6.like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。
    7.不要在列上进行运算
    8.NOT IN可以NOT EXISTS代替,id<>3则可使用id>3 or id<3来代替。
    9.Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。
    10.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
    11.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量日志。
    12.删除临时表,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
    13.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 
    14.如果数据变动很频繁,不用每次都改数据库,一定要用内存池,不仅可以减少数据库的压力,同时也减少bug
    15.封装sql对数据库的读写操作,不仅方便还减少出错
    16.别搞太多的库,联合查询我觉得使用特别不方便,一条sql访问超过3个库,感觉心态都不好了。。。。

  • 相关阅读:
    C# Socket 入门2(转)
    C# Socket 入门1(转)
    StructLayout特性(转)
    [转载]U3d常规性能优化技巧
    Python语言系统学习(七)
    Python语言系统学习(五)
    python语言系统学习(六)
    python语言系统学习(四)
    白话经典算法-常见排序算法的实现与性能比较
    最快的内容查找算法-----暴雪的Hash算法
  • 原文地址:https://www.cnblogs.com/byfei/p/14104088.html
Copyright © 2011-2022 走看看