mysql:
软件安装
rpm -qa |grep 名字 查询软件是否安装,安装就会显示信息
rpm 软件包 -ivh i是install,v是显示运行日志,h进度条
mysql的逻辑架构:
连接层:连接数据库
服务层:将我们写的sql的分析和优化。是否建立索引;select查询还会使用内部缓存提升性能
引擎层:myISM和innoDB用的多,根据不同的引擎功能和优势不同选取,可拔插
存储层:最终将数据存储到文件系统上
mysql> show engine
-> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
mysql> show variables like '%storage_engine%';
+------------------------+--------+
| Variable_name | Value |
+------------------------+--------+
| default_storage_engine | InnoDB |
| storage_engine | InnoDB |
+------------------------+--------+
2 rows in set (0.00 sec)
默认引擎MyISAM和innoDB:
对比项 | MYISAM | INNODB的比较 |
---|---|---|
主外键 | 不支持 | 支持 |
持事务 | 不支持 | 支持 |
行表锁 | 表锁,即使操作一条记录也会锁住整个表,不适合高并发操作 | 行锁,操作只锁某一行,不对其他行产生影响,适合高并发 |
表空间 | 小 | 大 |
关注点 | 性能 | 事务 |
6、mysql性能优化下降原因:
单值索引: create index idx_user_name on user(name); 默认idx代表索引
复合索引:create index idx_user_nameEmail on user(name,email);
程序员写顺序 :select from join on where groupBy having oderBy limit
数据库服务层执行顺 、机读:from join on where groupBy having select oderBy limit
7、常见通用的join:
内连接:SELECT * from student st INNER JOIN score s on st.s_id=s.s_id;
左连接:SELECT * from student st LEFT JOIN score s on st.s_id=s.s_id;
右连接:SELECT * from student st RIGHT JOIN score s on st.s_id=s.s_id;
左边独有部分:SELECT * from student st LEFT JOIN score s on st.s_id=s.s_id WHERE s.s_id IS NULL;
右边独有部分:SELECT * from student st RIGHT JOIN score s on st.s_id=s.s_id WHERE st.s_id IS NULL;
去重两个集合:SELECT * from student st LEFT JOIN score s on st.s_id=s.s_id
UNION
SELECT * from student st RIGHT JOIN score s on st.s_id=s.s_id;
(上面的full outer join 是Oracle语法)
两集合去重:SELECT * from student st LEFT JOIN score s on st.s_id=s.s_id WHERE s.s_id IS NULL
UNION
SELECT * from student st RIGHT JOIN score s on st.s_id=s.s_id WHERE st.s_id IS NULL;
8、索引:
1、索引是一种数据结构,排好序的快速查找数据结构。帮助mysql高效获取数据的数据结构
2、我们平常说的索引结构,如果没有特别指明,都是指B+树(多路搜索树,并不一定是二叉的)结构组织的索引。
其中聚集索引、次要索引、覆盖索引、复合索引、前缀索引,唯一索引默认都是使用B+树索引。还有哈希索引等(hashIndex)。
3、数据之外,数据库还维护着满足特定查找算法的数据结构,这些数据结构以某种方式指向数据,
这样就可以在这些数据结构基础上实现高级的查找算法,这种数据结构就是索引。
4、一般来说索引本身也很大,不可能全部存储在内存中,因此索引会以索引文件形式存储在磁盘上。
5、索引会影响排序和查找
功能:排序和方便查找
优势:
1、类似于图书馆建书目录索引,提高数据检索的效率,降低数据库的IO成本;
2、通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗;
劣势:
1、实际上索引也是一张表,该表保存了主键和索引字段,并指向实体表的记录,所以索引列也要占用空间。
2、虽然索引提升了查询速度,然而却会降低了更新表的速度。如insert、update、delete。需要更新索引文件对应的索引列字段。
3、索引只是提高效率的因素,如果你的mysql大数量的表,就需要花费大量的时间研究建立最优秀的索引,或优化查询语句。
创建:CREATE [unique] INDEX idx_tableName ON table(columname(length));
ALTER table ADD[unique] INDEX idx_tableName ON (columname(length)) ;
删除:DROP INDEX [indexName] ON table;
查看:SHOW INDEX FROM table;
// 有四种方式来添加数据表的索引:
// 1. 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL
ALTER TABLE tbl_name ADD PRIMARY KEY (column_list);
// 2. 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)
ALTER TABLE tbl_name ADD UNIQUE index_name(column_list);
// 3. 添加普通索引,索引值可出现多次
ALTER TABLE tbl_name ADD INDEX index_name(column_list);
// 4. 该语句指定了索引为 FULLTEXT, 用于全文索引
ALTER TABLE tbl_name ADD FULLTEXT index_name(column_list);
检索原理:
查找过程:假如查找数据项29,首先会把磁盘1加载到内存,此时发生一次io,在内存中用二分查找确定29是在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短忽略不计,P2指针指向然后加载磁盘3到内存,第二次io,然后加载磁盘块8到内存,第三次IO,同时内存中做二分查找到29,总共3次io。
需要创建索引的情况
主键自动建立唯一索引;
查询中与其他表关联的字段,外键关系建立索引;
频繁作为查询条件的字段应该创建索引;(高并发情况下,倾向创建组合索引)
查询中排序的字段,排序字段若通过索引去访问将大大提高索引速度;
查询中统计或者分组字段
不需要创建索引的情况
表记录太少;少于300万数据,理论500-800万数据
经常增删改的表;需要重新更改索引文件
如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果;(例如国籍,差异不多吗,大家都是中国)
WHERE 条件里用不到的字段不要创建索引;
9、性能分析:explain
MySQL 常见瓶颈
CPU: CPU在饱和的时候,一般发生在数据装入内存或从磁盘上读取数据的时候;
IO: 磁盘I/O瓶颈发生在装入数据远大于内存容量的时候;
服务器硬件的性能瓶颈: top, free, iostat 和 vmstat 来查看系统的性能;
Explain
使用EXPLAIN关键字,可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句的,从而分析查询语句或是表结构的性能瓶颈;
使用语法: Explain + SQL语句
mysql> explain select * from student;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | student | ALL | NULL | NULL | NULL | NULL | 9 | |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
从EXPLAIN结果中获取那些信息:
1、表的读取顺序;
2、数据读取操作的操作类型;
3、哪些索引可以使用;
4、哪些索引被实际使用;
5、表之间的引用;
6、每张表有多少行被优化器查询;
Explain 各字段解释:
mysql> explain SELECT * from student where s_id IN
-> ( SELECT a.s_id FROM
-> (SELECT s_id,c_id from score where c_id='01') a
-> INNER JOIN (SELECT s_id,c_id from score where c_id='02') b
-> on a.s_id=b.s_id);
+----+--------------------+------------+-------+---------------+---------+---------+------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+-------+---------------+---------+---------+------+------+--------------------------------+
| 1 | PRIMARY | student | ALL | NULL | NULL | NULL | NULL | 9 | Using where |
| 2 | DEPENDENT SUBQUERY | <derived3> | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
| 2 | DEPENDENT SUBQUERY | <derived4> | ALL | NULL | NULL | NULL | NULL | 6 | Using where; Using join buffer |
| 4 | DERIVED | score | index | NULL | PRIMARY | 124 | NULL | 20 | Using where; Using index |
| 3 | DERIVED | score | index | NULL | PRIMARY | 124 | NULL | 20 | Using where; Using index |
+----+--------------------+------------+-------+---------------+---------+---------+------+------+--------------------------------+
5 rows in set (0.00 sec)
mysql> explain SELECT * from student st LEFT JOIN score s on st.s_id=s.s_id WHERE s.s_id IS NULL UNION SELECT * from student st RIGHT JOIN score s on st.s_id=s.s_id WHERE st.s_id IS NULL;
+----+--------------+------------+--------+---------------+---------+---------+--------------+------+-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+------------+--------+---------------+---------+---------+--------------+------+-------------------------+
| 1 | PRIMARY | st | ALL | NULL | NULL | NULL | NULL | 9 | |
| 1 | PRIMARY | s | ref | PRIMARY | PRIMARY | 62 | demo.st.s_id | 1 | Using where; Not exists |
| 2 | UNION | s | ALL | NULL | NULL | NULL | NULL | 20 | |
| 2 | UNION | st | eq_ref | PRIMARY | PRIMARY | 62 | demo.s.s_id | 1 | Using where; Not exists |
| NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------+------------+--------+---------------+---------+---------+--------------+------+-------------------------+
5 rows in set (0.00 sec)
--------------------------------------------------------------------------------------------------------
id: 表示查询中执行select子句或操作表的顺序
id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行;id相同,执行顺序由上至下;
--------------------------------------------------------------------------------------------------------
select_type:表示sql查询的类型,主要用于区别普通查询,联合查询,子查询等复杂查询;
SIMPLE: 简单的select查询,查询中不包含子查询或者UNION;
PRIMARY: 查询中若包含任何复杂的子部分,最外层查询则被标记为PRIMARY,最后加载的;
SUBQUERY: 在SELECT或WHERE列表中包含了子查询;
DERIVED: 在FROM列表中,包含的子查询被标记为DERIVED(衍生),MySQL会递归执行这些子查询,
把结果放在临时表里;
UNION: 若第二个SELECT出现在UNION之后,则被标记为UNION;若UNION包含在FROM子句的子查询中,
外侧SELECT将被标记为 DERIVED;
UNION RESULT: 从UNION表获取结果的SELECT;
--------------------------------------------------------------------------------------------------------
table: 显示这一行的数据是关于哪张表的;
--------------------------------------------------------------------------------------------------------
type:优化级别,从最好到最差依次是: system>const>eq_ref>ref>range>index>ALL;
system: 表中只有一行记录(等于系统表),这是const类型的特例,平时不会出现,可以忽略不计;
const: 表中只有多行记录表示通过索引一次就找到了,const用于比较primary key 或者 unique索引;
因为只匹配一行数据,所以查询很快;如果将主键至于where列表中,MySQL就能将该查询转换为一个常量;
eq_ref: 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配;常见于主键或唯一索引扫描;
ref: 非唯一性索引扫描,返回匹配某个单独值的所有行;本质上也是一种索引访问,它返回所有匹配某个单独值的行,
然而,它可能会找到多个符合条件的行,所以它应该属于查找和扫描的混合体;
range: 只检索给定范围的行,使用一个索引来选择行;key 列显示使用了哪个索引;一般就是在WHERE语句
中出现between,<,>,in等的查询;这种范围扫描索引比全表扫描要好,因为它只需要开始于索引的某一点,
而结束于另一点,不用扫描全部索引;
index: Full Index Scan, index与ALL区别为index类型只遍历索引树,这通常比ALL快,因为索引文件通常
比数据文件小;(也就是说,虽然all和index都是读全表,但index是从索引中读取的,而all是从硬盘中读的)
all: Full Table Scan,将遍历全表以找到匹配的行;
一般来说,得保证查询至少达到range级别,最好能达到ref;
--------------------------------------------------------------------------------------------------------
possible_keys:显示可能应用在这张表中的索引,一个或多个;查询涉及到的字段上若存在索引,
则该索引将被列出,但不一定被实际查询使用;
key:表示实际使用的索引,如果为NULL,则没有使用索引、没建索引或索引失效;
查询中若使用了覆盖索引,则该索引仅出现在key列表中;
覆盖索引:就是查询的字段column1 column2和建立索引的字段个数和顺序全都一致。
--------------------------------------------------------------------------------------------------------
key_len:表示使用到索引中的字节数,可通过该列计算查询中使用的索引的长度;在不损失精确性的情况下,长度越短越好;
key_len显示的值为索引字段的最大可能长度,而非实际使用长度,即 key_len 是根据表定义计算而得,不是
通过表内检索出的;
--------------------------------------------------------------------------------------------------------
ref:显示索引的哪一列被使用了,如果可能的话,是一个常数;说明哪些列或常量被用于查找索引列上的值;
--------------------------------------------------------------------------------------------------------
rows:根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数;
--------------------------------------------------------------------------------------------------------
Extra:包含不适合在其他列中显示,但十分重要的额外信息;
Using filesort: 说明MySQL会对数据使用一个外部的索引排序,而不是按照索引表内的索引顺序进行读取,
MySQL中无法利用索引完成的排序操作称为"文件排序";
Using temporary: 使用了临时表保存中间结果,MySQL在对查询结果排序时,使用临时表;常见于排序
order by和分组查询group by;
Using index: 表示相应的select操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率
不错!如果同时出现using where,表明索引被用来执行索引键值的查找;如果没有同时出现using where,表明
索引用来读取数据而非执行查找操作
覆盖索引:就是select的数据列只用从索引中就能够取得,不必读取数据行,MySQL可以利用索引返回select列表
中的字段,而不必根据索引再次读取数据文件,换句话说,查询列要被所建的索引覆盖;
Using where: 表明使用了where过滤;
Using join buffer: 使用了连接缓存;
impossible where: where 子句的值总是false,不能获取到任何元组;
10、索引优化:explain
Join语句的优化
尽可能减少Join语句中的NestedLoop的循环总次数,"永远用小结果集驱动大的结果集";
优先优化NestedLoop的内层循环;
保证Join语句中被驱动表上Join条件字段已经被索引;
当无法保证被驱动表的Join条件字段被索引且内存资源充足的前提下,不要太吝啬JoinBuffer的设置;
索引失效
1、索引全值匹配、索引覆盖的意识;
2、索引最佳左前缀法则,指的是查询从索引的最左前列开始并且不跳过索引中的列;(带有第一个索引或者以及连续就可以)
3、不在索引列上做任何操作(计算,函数,(自动or手动)类型转换),会导致索引失效而转向全表扫描;(字符串不加单引号,会发生类型转换导致索引失效)
4、存储引擎不能使用索引中范围条件右边的列;(解决方案就是新键一个去掉那个带范围的新索引,含范围前后字段列)
5、尽量使用覆盖索引(只访问索引的查询(索引列或查询列一致)),减少select *;
6、MySQL在使用不等于(!= 或者 <>)的时候,无法使用索引会导致全表扫描;
7、is null, is not null也无法使用索引;
8、like 以通配符开头(%abc...%或者%abc...),MySQL索引失效,会变成全表扫描的操作;因此,可以使用like abc%,
或者使用覆盖索引解决like '%字符串%'索引失效的问题;
9、字符串不加单引号,索引失效;
10、少用or,用它来连接时,会导致索引失效;
总结:
对于单键索引,尽量选择针对当前Query过滤性更好的索引;
在选择组合索引的时候,当前Query中过滤型最好的字段在索引字段顺序中,位置越靠前越好;
在选择组合索引的时候,尽量选择可以能够包含当前Query中的WHERE子句中更多字段的索引;
尽可能通过分析统计信息和调整Query的写法来达到选择合适索引的目的;
优化总结口诀
全值匹配我最爱,最左前缀要遵守;
带头大哥不能死,中间兄弟不能断;
索引列上少计算,范围之后全失效;
LIKE百分写最右,覆盖索引不写星;
不等空值还有or,索引失效要少用;
VAR引号不可丢,SQL高级也不难!
案例:
CREATE INDEX idx_test03_c1234 on test03(c1,c2,c3,c4);
1、
EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c2 = 'a2' and c4 = 'a4' and c3 ='a3';
EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c2 = 'a2' and c3 ='a3' and c4 = 'a4';
EXPLAIN SELECT * FROM test03 WHERE c4 = 'a4' and c3 ='a3' and c2 = 'a2' and c1 = 'a1' ;
索引居然还可以用!!mysql对查询语句优化 特别是常量,因此才会内部进行了顺序的调整从而用上了索引
2、EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c2 = 'a2' and c3>'a3' and c4='a4';
c1和c2用上了索引,从c3开始就是range了,c4就没法用索引了
3、 换个顺序
EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c2 = 'a2'and c4>'a4' and c3='a3';
mysql自己会调整顺序,c1,c2,c3,c4都用到了索引,c4被调整到了最后,key_len说明c4被调整了到了最后面;
所以type是range。
4、EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c2 = 'a2'and c4='a4' ORDER BY c3;
用上了order by 本来c2和c4中间断了c3,如果order by c3会怎样?
原因:索引两大功能:查找和排序。c1,c2用到了索引,用于查找。c3也用到了索引,用于排序。
---------------------------------------------------------------------------------------------------------
5、 去掉c4
EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c2 = 'a2'ORDER BY c3;
结果一样--------------------------------------------------------------------------------------------------
6、 如果把order by c3 改为c4呢
EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c2 = 'a2'ORDER BY c4;
用到了索引c1 c2,但出现了Using filesort
7、EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c5 = 'a5'ORDER BY c2,c3;
c1用到了索引 ,c2,c3用在了排序。
8、EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c5 = 'a5'ORDER BY c3,c2;
顺序调整了一下,用到了索引c1,但 出现了Using filesort
9、EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c2 = 'a2' ORDER BY c2,c3;
ref的type优化,都ok
10、 多了个c5,但是对结果没有影响。
EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c2 = 'a2' and c5 = 'a5' ORDER BY c2,c3;
11、 c3,c2排序却没有filesort
EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c2 = 'a2' and c5 = 'a5' ORDER BY c3,c2;
order byc3,c2不出现filesort的特殊原因就是因为排序字段c2已经是一个常量(c2='a2')了。
所以相当于 order by c3,'a2常量'
12、EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c4 = 'a4' GROUP BY c2,c3
c4是干扰项,ok啦
对比:EXPLAIN SELECT * FROM test03 WHERE c1 = 'a1' and c4 = 'a4' GROUP BY c3,c2
出现 useing filesort
记住:分组之前,肯定先排序。对于索引优化来说,其实都差不多
11、小表驱动大表 in or exists
案例说明:如果输出需要A,假如A的个数<B的数量使用exists,大于就是用in
mysql> select * from score;
+------+------+---------+
| s_id | c_id | s_score |
+------+------+---------+
| 01 | 01 | 80 |
| 01 | 02 | 90 |
| 01 | 03 | 99 |
| 02 | 01 | 70 |
| 02 | 02 | 60 |
| 02 | 03 | 80 |
| 03 | 01 | 80 |
| 03 | 02 | 80 |
| 03 | 03 | 80 |
| 04 | 01 | 50 |
| 04 | 02 | 30 |
| 04 | 03 | 20 |
| 05 | 01 | 76 |
| 05 | 02 | 87 |
| 06 | 01 | 31 |
| 06 | 03 | 34 |
| 07 | 02 | 89 |
| 08 | 03 | 98 |
| 10 | 03 | 20 |
| 11 | 03 | 30 |
+------+------+---------+
20 rows in set (0.00 sec)
mysql> select * from student;
+------+--------+------------+-------+
| s_id | s_name | s_birth | s_sex |
+------+--------+------------+-------+
| 01 | 赵雷 | 1990-01-01 | 男 |
| 02 | 钱电 | 1990-12-21 | 男 |
| 03 | 孙风 | 1990-05-20 | 男 |
| 04 | 李云 | 1990-08-06 | 男 |
| 05 | 周梅 | 1991-12-01 | 女 |
| 06 | 吴兰 | 1992-03-01 | 女 |
| 07 | 郑竹 | 1989-07-01 | 女 |
| 08 | 王菊 | 1990-01-20 | 女 |
| 09 | wang | 1990-01-20 | 男 |
+------+--------+------------+-------+
9 rows in set (0.00 sec)
mysql> explain select * from student where exists (select 1 from score s where s.s_id=student.s_id);
+----+--------------------+---------+------+---------------+---------+---------+-------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------+------+---------------+---------+---------+-------------------+------+-------------+
| 1 | PRIMARY | student | ALL | NULL | NULL | NULL | NULL | 9 | Using where |
| 2 | DEPENDENT SUBQUERY | s | ref | PRIMARY | PRIMARY | 62 | demo.student.s_id | 1 | Using index |
+----+--------------------+---------+------+---------------+---------+---------+-------------------+------+-------------+
2 rows in set (0.00 sec)
mysql> explain select * from student where s_id in (select s_id from score);
+----+--------------------+---------+----------------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------+----------------+---------------+---------+---------+------+------+-------------+
| 1 | PRIMARY | student | ALL | NULL | NULL | NULL | NULL | 9 | Using where |
| 2 | DEPENDENT SUBQUERY | score | index_subquery | PRIMARY | PRIMARY | 62 | func | 1 | Using index |
+----+--------------------+---------+----------------+---------------+---------+---------+------+------+-------------+
2 rows in set (0.00 sec)
12、Oder By 关键字优化
CREATE INDEX idx_A_ageBirth ON tbla(age,birth);
正常的有:
EXPLAIN SELECT * FROM tbla WHERE age>20 ORDER BY age;
EXPLAIN SELECT * FROM tbla WHERE age>20 ORDER BY age,birth;用上索引。
EXPLAIN SELECT * FROM tbla WHERE age>20 ORDER BY age desc,birth desc; 默认升序
出现Using filesort:
EXPLAIN SELECT * FROM tbla WHERE age>20 ORDER BY birth;
EXPLAIN SELECT * FROM tbla WHERE age>20 ORDER BY birth,age;
EXPLAIN SELECT * FROM tbla WHERE age>20 ORDER BY age asc,birth desc;
13、group by 关键字优化
和oder by一致,尽量少用having,多用where
14、SQL调优:explain
开启慢查询日志,设置阈值,比如超过5秒钟的就是慢SQL,并将它抓取出来。观察一天
总结:
1.慢查询的开启并捕获
2.explain+慢SQL分析
3.show profile 查询SQL在Mysql服务器里面的执行细节和生命周期情况
4.SQL数据库服务器的参数调优。
15、主从复制
MySQL 复制过程分为三步:
master将改变记录到二进制日志(binary log),这些记录过程叫做二进制日志事件,binary log events;
slave 将 master 的 binary log events 拷贝到它的中继日志(relay log);
slave 重做中继日志中的事件,将改变应用到自己的数据库中,MySQL复制是异步的且串行化的;
复制的基本原则
每个slave只有一个master;
每个slave只能有一个唯一的服务器ID;
每个master可以有多个slave;
复制的最大问题: 延时;