高性能mysql的读书笔记(一)

1、  备份数据库hive:mysqldump  -uhive  -phive hive  > test.sql 。其中用户为hive,用户密码为hive

2、  备份数据库的某表,比如test1、test2:mysqldump –uhive  –phive --database hive –table test1 –table test2 >test1_test2.sql

3、  恢复数据库hive:mysql  –uhive -phive  < test.sql

4、  恢复数据库中的某张表,比如hive数据库中的test1表:mysql  -uhive -phive –database hive < test1.sql

5、  Mysql最重要、与众不同的特性是它的存储引擎架构,这种架构的设计将查询处理及其他系统任务和数据的存储/提取相分离。这种处理和存储分离的设计可以在使用时根据性能、特性,以及其他需求来选择数据存储的方式

6、  对于select语句,在解析查询之前,服务器会先检查查询缓存,如果能够在其中找到对应的查询,服务器就不必再执行查询解析。优化和执行的整个过程。

7、  在处理并发读或者写时,可以通过实现一个由两种类型的锁组成的锁系统来解决问题。这两种类型的锁通常被称为共享锁和排他锁,也叫读锁和写锁

8、  事务就是一组原子性的SQL查询,或者说一个独立的工作单元。如果数据库引擎能够成功地对数据库应用该组查询的全部语句,那么就执行该组查询。如果其中有任何一条语句因为崩溃或者其他原因无法执行,那么所有的语句都不会执行。也就是说,事务内的语句,要么全部执行成功,要不全部执行失败。由start transaction语句开始事务,然后要么使用commit提交事务,要么使用rollback撤销所有的修改

9、  ACID表示原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)

10、             SQL定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改,拿些在事务内和事务间是可见的,那些是不可见的。READ UNCOMMITED、READ  COMMITED、REPEATEDREAD、SERIALIZABLE

11、 InnoDB目前处理死锁的方法是,将持有最少行级排他锁的事务进行回滚

12、Mysql默认采用自动提交模型(AUTOCOMMIT),也就是说,如果不是显式地开始一个事务,则每个查询都被当做一个事务执行提交操作。

13、 通过SET SESSION TRANSACTION ISOLATION  LEVEL  READ COMMITED设计MySQL的隔离级别为READ COMMITED

14、MySQL服务器层不管理事务,事务是由下层的存储引擎实现的。所有在同一个事务中,使用多种存储引擎是不可靠的。InnoDB是事务型的,而MyISAM表是非事务型的。如果事务需要回滚,非事务型的表上的变更就无法撤销

15、 MVCC多版本并发控制,不同存储引擎的MVCC实现不同,典型的有乐观并发控制和悲观并发控制。MVCC只在REPEATABLE  READ和READ  COMMITTED两个隔离级别工作。

16、 InnoDB的MVCC是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个是保存了行的创建时间,一个保存行的过期时间。当然存储的并不是实际的时间值,而是系统版本号,每开始一个新的事物,系统版号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较

17、表相关信息的查询可以通过:show  table  status like  ‘employees’

18、MySQL的默认事务型引擎是InnoDB,它被设计用来处理大量的短期事务,短期事务大部分是正常提交的,很少会被回滚。

19、MySQL 5.1中建议使用InnoDBplugin

20、InnoDB表是基于聚簇索引建立的

21、InnoDB的行为负责,建议读官方手册“InnoDB事务模型和锁”一节

22、 Collation 表示表的默认字符列排序规则

23、MyISAM不支持事务和行级锁,而且有一个毫无疑问的缺陷是崩溃后无法安全恢复

24、引擎改变,将表从一个引擎修改为另一个引擎最简单的办法是使用ALTER  TABLE语句:ALTERTABLE TEST ENGINE = InnoDB;该方法花费的时间久,替代的方法是利用导出与导入方法,手工进行表的复制。

25、mysqldump工具将数据导出到文件,然后修改文件中的create  table语句的存储引擎选项,注意同时修改表名,因为同一个数据库中不能存在相同的表名,即使它们使用的是不同的存储引擎。同时mysqldump默认会自动在create  table语句前加上droptable语句。

26、也可以通过创建与查询来改变表的引擎,create  table  test1 like  test; alter table test2engin=InnoDB;Insert into test1 select * from test。如果数据流不大的话,这样做工作得很好,但是如果数据量很大,则可以考虑做分批处理。针对每一段数据提交事务操作。Start  transaction; inset intotest1 select * from test where id between x and y; commit;

27、 如果能理解MySQL在存储引擎和服务层之间处理查询时如何通过API来回交互,就能抓住MySQL的核心基础架构精髓

28、 基准测试是MySQL针对系统设计的一种压力测试

29、可以通过mysql  -uhive  -phive -e,比如mysql  -uhive  -phive -e  ‘show  global variables’执行mysql语句 ,其中用户为hive,用户密码为hive

30、SHOW  PROFILES 。通过SET PROFILING = 1,然后在服务器上执行的所有语句,都会测量其耗费的时间和其他一些查询执行状态变更相关的数据。Show  profile  for query 1;

31、Show status命令返回了一些计数器。既有服务器级别的全局计数器,也有基于某个连接的会话级别的计数器。例如执行show  global  status则可以查看服务器级别的从服务器启动时开始计算的查询次数统计。最用用的计数器包括句柄计数器(handler counter)、临时文件和表计数器show status where Variable_name like 'Handler%'

32、 Show  processlist捕获show  processlist的输出

33、Show index from test显示表test的索引

34、 Mysql数据类型的优化(1)更小的通常更好,应该尽量使用可以正确存储数据的最小数据类型、(2)简单就好,简单数据类型的操作通常需要更小的CPU周期。例如整型比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整型比较更加复杂、(3)尽量避免NULL,通常情况下最好指定列为NOT NULL,除非真的需要存储NULL值。如果查询中包括可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引、索引统计和值比较都更加复杂,可为NULL的列被索引时,每个索引记录需要一个额外的字节

35、整数类型有:TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT。分别使用8,16,24,32,64位存储空间。整型类型有可选的unsigned属性,如TINYINT UNSIGNED

36、DECIMAL类型用于存储精确的小数。在MySQL5.0和更高的版本,DECIMAL类型执行精确计算。FLOAT 和DOUBLE类型支持使用标准的浮点运算进行近似计算。相对而言,CPU直接支持原生浮点计算,所有浮点运算明显更快。对于DECIMAL,每四个字节存9个数字。例如DECIMAL(18,9),小数点两边各存储9个数,一共使用9个字节,其中有一个是小数点

37、Varchar类型用于存储可变长字符串,它比定长类型更节省空间,但是MySQL表使用ROW_FORMAT=FIXED创建的话,每行都会使用定长存储。Varchar需要使用1或2个额外字节记录字符串的长度:如果列的最大长度小于或等于255字节,则使用一个字节表示,否则使用2个字节表示。Varchar省空间,但是在update时可能导致额外花费

38、CHAR类型是定长的:MySQL根据定义的字符串长度分配足够的空间。当存储CHAR值时,MySQL会删除所有的末尾空格,(在新版本中VARCHAR也是这样实现的,也就是说CAHR和VARCHAR在逻辑上是一样的,区别是存储格式上),CHAR适合存储很短的字符串,或者所有值都接近一个长度。对于经常变更的数据,CHAR也比VARCHAR在存储空间上有效率,不易产生碎片

39、 使用枚举:create  table  enum_test(e ENUM(‘fish’,  ‘apple’,  ‘dog’) not null)。枚举有个不好是:当VARCHAR列和ENUM列进行关联时则慢很多。一个通用设计实践,在“查找表”时采用整数主键而避免采用基于字符串的值进行关联。

40、MySQL时间:DATETIME 类型保存大范围的值,从1001年到9999年,精确到秒,使用八个字节;TIMESTAMP 类型保存了从1970年1月1日午夜以来的秒数,只使用4个字节,只能记录到2038年时间。通过FROM_UNIXTIME()函数把UNIX的时间戳转换成日期。并提供了UNIX_TIMESTAMP()函数把日期转换成Unix时间戳。

41、标识列的类型最好是整型类型,对于标识列EMUN和SET类型通常都是糟糕的选择,如果可能,应该避免使用字符串类型作为标识列,因为它们很消耗空间,并且通常比数字类型慢

42、 MySQL  schema设计中的陷阱:(1)太多的列、(2)太多的关联,单个查询最好在12个表以内做关联

43、MySQL会在索引中存储NULL值,而Oracle则不会

44、Alter table操作一般会引起表重建,但是并不是所有都是这样的。例如,有两种方法可以改变或者删除一个列的默认值(一个方法快,一个慢)。(一)alter  table  test modify  column  num tinyint(3)  not  null default  5;这个操作直接重建了表,其实列的默认值实际上存在表的.frm文件中。然而MySQL还没有采用这种优化,所有modify  column操作都将导致表的重建;(二)通过alter  column操作来改变列的默认值alter  table  test alter  column  num set  default  5;

45、 通过直接修改.frm文件可以很快对表的一些性质进行改变,但是要承担一定的风险。

46、快速创建MyISAM索引,为了高校载入数据到MyISAM,有一个常用的技巧是先禁用索引、载入数据,然后重新启用索引:alter  table  test disable  keys;  load data;alter  table  test enable  keys;但是这个方法对唯一索引无效(高性能mysql 138页)

47、索引可以包含一个或多个列的值,如果索引包含多个列,那么列的顺序也十分重要,因为mysql只能高效的使用索引的最左前缀列。

48、B-Tree索引的限制:如果不是按照索引的最左列开始查找,则无法使用索引。

49、索引列的顺序会影响搜索的效率,在优化的时候,可能需要使用相同的列但顺序不同的索引来满足不同类型的查询需求。

50、索引选择的指标:不重复的索引值和数据表的记录总数的比值,范围从0到1,越大越好,select  count(distinct  left(name,2))/count(*)  from  test;

51、可以通过参数optimizer_switch来关闭索引合并功能。也可以使用ignore index提示让优化器忽略丢某些索引。这都是调试索引的方法

52、二级索引需要两次索引,在于二级索引中保存的“行指针”的实质,二级索引叶子节点保存的不是指向行的物理位置的指针,而是行的主键值

53、InnoDB 和MYISAM在存储和索引的表示(PDF高性能mysql  167页)

54、在InnoDB表中,按主键顺序插入行,这样能够在一般情况下高效工作,但是这样也有它的缺点,就是在并发工作负载时,因为所有的插入都发生在主键的上界,高并发可能会导致间隙锁竞争。

55、在范围条件中:对于范围条件查询,MySQL无法再使用范围列后面的其他索引列,但是对于“多个等值条件查询”则没有这个限制

56、表的维护,可以通过check  table  test来找出大多数的表和索引的错误。在MyISAM中,可以通过repair  table test来修复它们。在InnoDB中,如果遇到数据损坏,最重要是找出损坏的原因,否则很有可能不断地损坏。可以通过innodb_force_recovery参数进入InnoDB的强制恢复模式修复数据。

57、InnoDB在打开某些INFORMATION_SCHEMA表,或者使用show  table status  和show  index ,抑或在MySQL客户端开始自动补全功能的时候都会触发索引统计信息的更新,影响性能。可以通过关闭innodb_stats_on_metadata参数来避免。

58、查询性能低下最基础的原因是访问的数据太多了。

59、可以通过explain来了解mysql语句的执行过程的情况,如  explain select* from test。在explain语句中的type列反应了访问类型。访问类型有很多种,从全表扫描到索引扫描、范围扫描、唯一索引查询、常数引用等。它们的速度是从慢到快

60、在进行关联查询的时候,如:select  test.*,  test1.*, test2.*  from  test inner join  test1  using(num) inner  join  using (name)  ,mysql的优化器会优化我们的关联顺序。但是有时候优化器并不是最优的关联顺序,这时候,我们可以使用STRAIGHT_JOIN关键字重写查询,让优化器按照你认为最优的关联顺序执行(一般不推荐)

61、当需要关联的表超过optimizer_search_depth的限制的时候,就会选择“贪婪”搜索模式

62、 Mysql的子查询实现得非常糟糕。最糟糕的一类查询是WHERE条件中包含IN()的子查询语句。比如select  *   from film  where  film_id in  (select  film_id from  film_actor  where actor_id  =  1);Mysql的优化是:select  * from film  where  exists (select  * from  film_actor  where actor_id  =  1 and  film_actor.film_id  = film.film.film_id)。改进查询:select  file.*  from film  inner join  film_actor using(film_id)  where  actor =  1;

63、分区CREATE TABLE sales (
    id INT AUTO_INCREMENT,
    amount DOUBLE NOT NULL,
    order_day DATETIME NOT NULL,
    PRIMARY KEY(id, order_day)
) ENGINE=Innodb PARTITION BYRANGE(YEAR(order_day)) (
    PARTITION p_2010 VALUES LESS THAN(2010),
    PARTITION p_2011 VALUES LESS THAN(2011),
    PARTITION p_2012 VALUES LESS THAN(2012),
    PARTITION p_catchall VALUES LESSTHAN MAXVALUE);

64、Explain partitions select *from  test;通过explain来显示查询所用到的分区。MySQL在使用分区函数的列本身进行比较才能过滤分区,而不是根据表达式的值去过滤分区。

Explain partition  select  * from test  where  Year(day)=2010\G;

65、查询缓存:MySQL在某些场景下直接缓存完整的SELECT查询结构,也就是“查询缓存”。

66、服务器调优中,InnoDB最重要的选项是:innodb_buffer_pool_size和innodb_log_file_size.。innodb_log_buffer_size表示InnoDB写入到磁盘上的日志文件时使用的缓冲区的字节数,默认值为8M。一个大的日志缓冲区允许大量的事务在提交之前不写日志到磁盘。因此,如果你有很多事务的更新,插入或删除很操作,通过这个参数会大量的节省了磁盘I / O。innodb_log_file_size表示在一个日志组每个日志文件的字节大小。日志文件的总大小(innodb_log_file_size* innodb_log_files_in_group)。innodb_buffer_pool_size参数表示缓冲池字节大小,InnoDB缓存表和索引数据的内存区域

 

你可能感兴趣的:(mysql,高性能mysql)