MySQL性能优化最佳实践 - 12 MySQL性能优化的最佳20+条经验

本章有部分内容与《MySQL性能优化最佳实践 - 10 MySQL写出高效SQL》互为补充。

从程序员的角度优化

  • 数据库的操作越来越成为整个应的的性能瓶颈,这点对于WEB应用尤其明显。
  • 关于数据库性能,这不只是DBA才需要担心的事,更是程序员需要去关注的事情。
  • 当设计表结构和操作数据库(DML操作)时,需要注意数据操作的性能。

为查询缓存优化你的查询

大多数的MySQL服务器都开启了查询缓存

EXPLAIN 你的SELECT 查询

  • 使用EXPLAIN 关键字可以让你知道MySQL是如何处理你的SQL语句的。这可以帮你分析你的查询语句或是表结构的性能瓶颈。
  • EXPLAIN 的查询结果还会告诉你你的索引主键被如何利用的,你的数据表是如何被搜索和排序的等等。
  • 挑一个你的SELECT语句(推荐挑选那个最复杂的,有多表联接的),把关键字EXPLAIN加到前面。你可以使用phpmyadmin来做这个事。然后,你会看到一张表格。下面的这个示例中,我们忘记加上了group_id索引,并且有表联接。
  • 当我们为group_id字段加上索引后:我们可以看到,前一个结果显示搜索了7883 行,而后一个只是搜索了两个表的9 和16 行。查看rows列可以让我们找到潜在的性能问题。

Oracle Linux网卡参数默认设置导致ORA-603

环境:OEL6.8,ORACLE 11.2.0.4 双节点RAC
节点2 alert日志报错信息如下:

Fri Nov 24 09:11:42 2017
skgxpvfynet: mtype: 61 process 11799 failed because of a resource problem in the OS. The OS has most likely run out of buffers (rval: 4)
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/orcl2_ora_11799.trc  (incident=123381):
ORA-00603: ORACLE server session terminated by fatal error
ORA-27504: IPC error creating OSD context
ORA-27300: OS system dependent operation:sendmsg failed with status: 105
ORA-27301: OS failure message: No buffer space available
ORA-27302: failure occurred at: sskgxpsnd2
Incident details in: /u01/app/oracle/diag/rdbms/orcl/orcl2/incident/incdir_123381/orcl2_ora_11799_i123381.trc
Fri Nov 24 09:11:42 2017
skgxpvfynet: mtype: 61 process 11801 failed because of a resource problem in the OS. The OS has most likely run out of buffers (rval: 4)
opiodr aborting process unknown ospid (11743) as a result of ORA-603
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/orcl2_ora_11801.trc  (incident=123382):
ORA-00603: ORACLE server session terminated by fatal error
ORA-27504: IPC error creating OSD context
ORA-27300: OS system dependent operation:sendmsg failed with status: 105
ORA-27301: OS failure message: No buffer space available
ORA-27302: failure occurred at: sskgxpsnd2
Incident details in: /u01/app/oracle/diag/rdbms/orcl/orcl2/incident/incdir_123382/orcl2_ora_11801_i123382.trc
Dumping diagnostic data in directory=[cdmp_20171124091142], requested by (instance=2, osid=11743), summary=[incident=123380].

MySQL性能优化最佳实践 - 10 MySQL写出高效SQL

MySQL设计标准

  1. 数据库命名规范、统一,如vip_xxxx
  2. 表一旦设计好,字段只允许增加,不允许减少(drop column)
  3. 统一使用INNODB存储引擎,UTF8编码(整个数据库的编码统一为utf8_general_ci,为此不需要建立表的DDL上加上CHARACTER SET COLLATE utf8_general_ci)
  4. 需在设计阶段考虑如果访问量非常大,且不做scale out(横向扩展)表拆分的话,需读写分离,但读写分离注意主从复制有延迟的可能性
  5. 禁用stored procedure(包括存储过程,函数,触发器),容易将业务逻辑和DB耦合在一起,并且MySQL的存储过程、触发器、函数中存在一定的bug
  6. 禁止使用UUID()USER()这样的MYSQL INSIDE函数,对于复制来说是很危险的,会导致主备数据不一致,重要的是会严重影响mysql性能
  7. 表必须有主键,建议统一由auto_increment字段生成整型,不建议使用组合主键, 另外auto_increment主键字段只作为虚拟主键,不建议与业务数据处理有关联关系,如果把控不好,会有问题
  8. 库名、表名、字段名、索引名必须使用小写字母
  9. 多表join写SQL的时候,一定要给每个字段指定表名做前缀
  10. 如果应用使用的是长连接,应用必须具有自动重连的机制。但需避免每执行一个SQL去检查一次DB可用性

MySQL性能优化最佳实践 - 11 MySQL锁优化分析

不同索引加锁顺序的问题,模拟重现死锁

走索引的SQL语句,会涉及两把锁,在特定场景下就会产生交差锁等待

测试表结构及相关语句

mysql> show create table employees\G;
*************************** 1. row ***************************
       Table: employees
Create Table: CREATE TABLE `employees` (
  `emp_no` int(11) NOT NULL,
  `birth_date` date NOT NULL,
  `first_name` varchar(14) NOT NULL,
  `last_name` varchar(16) NOT NULL,
  `gender` enum('M','F') NOT NULL,
  `hire_date` date NOT NULL,
  `base_salaries` decimal(8,2) NOT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`),
  KEY `idx_emp_hire` (`hire_date`),
  KEY `idx_emp_no` (`emp_no`)
) ENGINE=InnoDB AUTO_INCREMENT=300151 DEFAULT CHARSET=utf8

alter table employees drop primary key;
create index idx_emp_no on employees(emp_no);
alter table employees add id int;
alter table employees change id id int not null auto_increment primary key;

flashback常用命令整理

flashback常用命令整理

打开数据库闪回

SQL> select name,open_mode,log_mode,force_logging,flashback_on from v$database;

NAME      OPEN_MODE            LOG_MODE     FOR FLASHBACK_ON
--------- -------------------- ------------ --- ------------------
ORCL      READ WRITE           ARCHIVELOG   NO  NO

SQL> archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /u01/app/arch/
Oldest online log sequence     246
Next log sequence to archive   249
Current log sequence           249

SQL> show parameter recovery

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string
db_recovery_file_dest_size           big integer 0
recovery_parallelism                 integer     0

alter system set log_archive_dest='';
alter system set db_recovery_file_dest_size=10g;
alter system set db_recovery_file_dest='/u01/app/fra';

# 2880单位是分钟minutes
alter system set db_flashback_retention_target=2880;

alter database flashback on;

MySQL性能优化最佳实践 - 08 SQL EXPLAIN解析

什么是归并排序?

如果需要排序的数据超过了sort_buffer_size的大小,说明无法在内存中完成排序,就需要写到临时文件中。若排序中产生了临时文件,需要利用归并排序算法保证临时文件中的记录是有序的。归并排序算法是分批将数据放到文件中进行排序,然后逐一按序合并。
简单来说是把在内存中无法直接排序的数据进行分批,每批已排序的结果分别放到文件中。用每个已排序的文件中第一行数据做进行比较,取出最小的值放到最终的合并排序文件中。重复以上操作,直到所有文件文件数据都放到合并排序文件中。

Oracle RMAN异机恢复归档RMAN-07518(供日志挖掘使用)及修改dbid步骤

# 原库:CRM (DBID=3657993631)  异机:DGT (DBID=1562574039)
sqlplus / as sysdba
exec dbms_backup_restore.nidbegin('dgt','DGT','3657993631','1562574039',0,0,10);

variable a number;
variable b number;
variable c number;

exec dbms_backup_restore.nidprocessdf(0,0,:a,:b,:c);
exec dbms_backup_restore.nidprocesscf(:a,:b);
exec dbms_backup_restore.nidend;

select dbid from v$database;

rman target /
catalog start with '/oradata/nfs/crmpn_rman/arc_temp';

run
{allocate channel ci type disk;
set archivelog destination to '/u01/';
restore archivelog all;
release channel ci;
}