查看Mysql支持的存储引擎
show ENGINE \G
设置表的存储引擎
create table table_name() ENGINE=InnoDB CHARSET=utf-8
修改表的存储引擎
alter table_name ENGINE MyISAM
创建索引语法
create [UNIQUE|FULLTEXT|SPATIAL] INDEX idx_name
[USING index_type]
ON table_name(idx_col_name)
MEMORY存储引擎时可以使用
HASH重要特征
BTree特征
适用于Hash和BTree索引
select * from table_name where key_col = 1 or key_col in (1,2,3);
只适用于btree索引
select * from table_name where key_col > 1 and key_col < 10;
select * from table_name where key_col like 'ab%' or key_col between 'a' and 'b';
HASH索引实际是全表扫描的
XA {START|BEGIN} xid [JOIN|RESUME]
XA START xid 用于启动一个带给定xid值的XA事务。每个XA事务必须有一个唯一的xid值
xid是一个XA事务标识符,用来标识一个分布式事务。xid值由客户端提供,MySQL服务器生成
xid包含三个部分
xid: gtrid [, bqual [, formatID ]]
XA END xid [SUSPEND [FOR MIGRATE]]
XA PREPARE xid
XA COMIT xid [ONE PHASE]
XA ROLLBACK xid
XA RECOVER
分布式关键在于如何确保分布式事务的完整性,以及在某个分支出现问题时的故障解决。
XA的相关命令就是提供给应用如何在多个独立的数据库之间进行分布式事务的管理,包括启动一个分支事务、使事务进入准备阶段以及事务的实际提交回滚操作等
举例:在DB1中插入一条记录,同时在DB2更新一条记录,两个操作作为同一事务提交或回滚
在数据库DB1中启动一个分布式事务和分支事务,xid的gtrid为”test”,bqual为”db1”
mysql> xa start 'test','db1';
mysql> insert into t_products values(5,2,'测试商品',50,'分布式测试');
mysql> xa end 'test','db1';
mysql> xa prepare 'test','db1';
mysql> xa recover;
*************************** 1. row ***************************
formatID: 1
gtrid_length: 4
bqual_length: 3
data: testdb1
在数据库DB2中启动一个分布式事务和分支事务,xid的gtrid为”test”,bqual为”db2”
mysql> xa start 'test','db2';
mysql> insert into producttype values(MD5('77'),now(),now(),'分布式测试');
mysql> xa end 'test','db2';
mysql> xa prepare 'test','db2';
mysql> xa recover;
*************************** 1. row ***************************
formatID: 1
gtrid_length: 4
bqual_length: 3
data: testdb2
提交分支事务
mysql> xa commit 'test','db1';
mysql> xa commit 'test','db2';
注意:两个事务都达到准备提交阶段后,一旦开始进行提交操作,需要确保全部分支提交成功
1.如果分支事务达到prepare状态,数据库异常重新启动,服务器重新启动后,可以继续对分支事务进行提交或者回滚操作,但是提交的事务没有写binlog,存在一定隐患。可能导致binlog恢复丢失部分数据。
2.如果存在复制的数据库,则有可能导致主从数据不一致。因为复制和灾难恢复都依赖于binlog
SQL注入攻击者可以利用它读取,修改或者删除数据库内的数据。一般的防火墙无法进行Sql注入拦截
“/*”或者”#”可以将后面的语句注释掉
对于JSP、Java开发的应用来防止SQL注入
String sql = "select userName from userName = ? and userPassword = ?";
PrepareStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1,name);
pstmt.setString(2,pwd);
ResultSet rs = pstmt.executeQuery();
SQL Mode定义MySql应该支持的SQL语法、数据校验等
SQL Mode 常用来解决
不同数据库迁移之前,通过SQL Mode可以使MySQL上的数据更方便迁移到目标数据库中
mysql> select @@sql_mode;
+----------------------------------------------------------------+
| @@sql_mode |
+----------------------------------------------------------------+
| STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+----------------------------------------------------------------+
set [session/global] sql_mode = ‘STRICT_TRANS_TABLES’ : 设置严格模式。当记录插入失败,直接失败。返回ERROR
-- 按照数据随机排序,并选择前10
select * from table_name order by rand() limit 10;
按照随机顺序检索数据行
可以检索出更多的分组聚合信息。with rollup反映的是一种OLAP思想
注意:
1.当使用ROLLUP时,不能同时使用ORDER BY
2.LIMIT用在WITH ROLLUP的后面
show status like 'Com_%';
查看事务提交回滚情况
- Com_commit
- Com_rollback
show status like 'Innodb_%';
对于回滚操作非常频繁的数据库,可能以为编写存在问题
extra:执行情况的说明和描述
id: 1
select_type: SIMPLE
table: region
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 3524
filtered: 100.00
Extra: NULL
索引用于快速找出在某个列中有一特定值的行。
**使用索引的主要条件是查询条件中需要使用索引关键字,如果是多列索引,需要满足最左前缀原则,才可使用,否则不能使用索引
mysql> show status like 'Handler_read%'
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 0 |
| Handler_read_last | 0 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
定期分析表和检查表
ANALYZE [LOCAL|NO_WRITE_TO_BINLOG] TABLE table_name [,table_name_2,...]
定期优化表
OPTIMizE [LOCAL|NO_WRITE_TO_BINLOG] TABLE table_name [,table_name_2,...]
注意:ANALYZE、CHECK、OPTIMIZE执行期间会对表进行锁定
当用load命令导入数据时,适当设置提高导入速度
对于MyISAM引擎表,设置如下
alter table table_name DISABLE KEYS;
loading the data
alter table table_name ENABLE KEYS;
DISABLE/ENABLE:打开/关闭MyISAM非唯一索引的更新
load data infile 'path' into table table_name;
对于InnoDB引擎表,设置如下
set unique_checks = 0 --导入数据前,关闭唯一性校验
set unique_checks = 1 --导入结束后,恢复唯一性校验
如果使用自动提交方式
set autocommit = 0 --关闭自动提交
set autocommit = 1 --打开自动提交
同一用户插入很多行,尽量使用多个值表的insert语句。缩减客户端与数据库之间的连接/关闭消耗
insert into table_name values(),(),()...
不同用户插入很多行,使用insert delayed得到更高的速度
OR之间的每个条件列都必须用到索引
show index from table_name --查看某表上索引
查询语句表名后面,添加use index提供希望mysql参考的索引列表
select * from table_name use index (idx_test_id) where ...
PROCEDURE ANALYSE() 对当前表进行分析
select * from table_name PROCEDURE ANALYSE()
适当考虑表的冗余字段,不需要在做关联查询,而让查询有更好的性能。
逆规范的好处是降低连接操作的需求和索引数目。甚至可能减少表数目。但是可能影响数据完整性。
MySQL在不同存储引擎下支持不同的锁机制
show status like 'table%';
Lock tables table_name_1 read local, table_name_2 read local
... --sql语句
Unlock tables
lock table table_name as alias read;
MyISAM的读写串行,在一定条件下,MyISAM表也支持查询和插入操作的并发进行
concurrent_insert --控制其并发插入的行为
写进程获取锁,读请求先到锁等待队列,写请求厚道,写锁会插入到读锁请求之前。(由于一特性,myISAM不适合大量更新和查询操作。大量更新操作会造成查询操作很难获得锁,从而一直阻塞。)
MyISAM与InnoDB最大不同:支持事务、采用行级锁。
事务隔离越严格,并发副作用越小,旦代价越大;事务隔离实质就是使事务在一定程度上”串行化”进行
show status like 'innodb_row_lock%'
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| Innodb_row_lock_current_waits | 0 |
| Innodb_row_lock_time | 0 |
| Innodb_row_lock_time_avg | 0 |
| Innodb_row_lock_time_max | 0 |
| Innodb_row_lock_waits | 0 |
+-------------------------------+-------+
如果锁争用的情况比较严重。还可以设置Innodb Monitors进一步观察锁冲突、数据行。具体分析原因
意向排它锁IX:事务打算给数据行加排它锁,事务在给定一个数据行加排它锁前必须取得该表的IX锁
– 共享锁
select * from table_name where … LOCK IN SHARE MODE
– 排它锁
select * from table_name where … FOR UPDATE
LOCK IN SHARE MODE:从数据依存关系确认某行记录是否存在,并确保没有人对这个记录进行update或者insert操作。但如果当前事务需要对该记录进行更新操作,可能会造成死锁‘
通过范围条件而不是相等条件检索数据,并请求共享排它锁时,InnoDB会给符合条件的已有数据记录的索引项加锁:对于键值在条件范围内但并不存在的记录,叫做间隙。InnoDB对这个间隙加锁
select * from table_name from col_1 > 100 for update
使用间隙的目的
1.防止幻读,满足相关隔离级别
2.满足恢复和复制
select @@tx_isolation;
复制本质:在SlaveMysql不断做基于binlog的复制
恢复机制:在一个事务未提交前,其他并发事务不能插入满足其锁定条件的任何记录(不允许幻读)。无论在ReadCommited或者RepeatableRead隔离级别下,InnoDB都要使用间隙锁
show variables --服务器静态参数值
show status --动态运行状态
show warnings
RAID 0:
RAID 1:
RAID 10
RAID 4
RAID 5
2.1. 避免对同一数据进行重复检索
2.2. 使用查询缓存
show variables like '%query_cache%'
2.3. 增加Cache层
2.2. 利用MySQL复制分流查询操作
- MySQL主从复制有效的分流更新操作和查询操作
- 具体实现:主服务器承担更新操作,多台服务器承担查询操作;主从之间通过复制进行数据同步;多台从服务器确保可用性;另一方面可以通过不同索引满足不同需要
- 缺点:当主数据库更新频繁或者网络出现问题时,主从之间的数据存在比较大的延迟更新造成查询结果和主数据库上有所差异
2.3. 采用分布式数据库结构
- 注:如果使用分布式架构数据库,必须采用InnoDBZ
- 对于没有删除行操作的MyISAM表,插入和查询可以并行进行,没有删除操作的表查询期间不会阻塞插入操作。对于需要执行删除操作的表,尽量在空闲时间执行批量删除,并在删除操作后进行optimize。避免将来更新阻塞其他操作
- 充分利用默认值
- 表尽量不适用自增长字段