1、mysql的配置文件。
在windows中是my.ini文件:
1)、log-bin:表示主从复制的日志文件,用于主从复制。
2)、log-error="SO3JFYNN8EW6GMO.err":表示错误日志。
3)、server-id=1:表示本机的序号为1。
4)、datadir=D:/mysql5.7/Data:存放数据库信息的目录,
2、mysql的架构从上到下分成四层:
1)、连接层:连接处理,授权认证,相关的安全方案。
2)、服务层:完成sql的优化,分析,缓存等功能。
3)、引擎层:负责存储和提取数据。
4)、存储层:数据存储层,主要将数据存储在文件系统之中,并完成与引擎的交互。
3、mysql引擎
1)查看使用的引擎:
show engins或者show
MYISAM和INNODB的比较
不支持主外键值对;支持
不支持事务;支持
表锁,不适合高并发;行锁,适合高并发
只缓存索引;缓存索引和数据,对内存要求更高
表空间小;表空间大
关注点在性能,更多情况下适合查询多的情况;关注点事务。
4、mysql性能优化下降原因
1)、查询语句写的烂
2)、索引失效
单值索引
create index idx_user_name on user(name)
复合索引
create index idx_user_name_email on user(name,email)
3)、查询有太多的join
4)、服务器调优及各个参数
5、mysql的执行顺序
机器从from开始读。
1)、内连接
select *from tableA A inner join tableB B on A.key=B.key。
2)、左外连接
select *from tableA A left join tableB B on A.key= B.key
当b没有的,用null补全。
3)、右外连接
select *from tableA A right join tableB B on A.key=B.key
当a没有时,用null补全
4)、左外连接,去除右表部分
select *from tableA A left join tableB B on A.key=B.key where B.key is null
a的独有,这此时b的用null补齐,所以此时b是为空的。
5)、右外连接,去除左表部分
select *from tableA A right join tableB B on A.key = B.key where A.key is null
6)、全连接(可以采用两者相加)union 可以组合并去重
select *from tableA A left join tableB B on A.key=B.key union
(select *from tableA A right join tableB B )
7)、中心空出来
select *from tableA A left join tableB B on A.key=B.key where B.key is null union
(select *from tableA A right join tableB B on A.key=B.key where A.key is null)
6、什么是索引
1)、索引是一种数据结构,在于提高查找效率。
排好顺序的快速查找数据结构。
数据库维护着满足特定算法的数据结构,这种数据结构以
某种方式指向数据,这样可以在这些数据结构上实现高级的超找
算法,这种数据结构称为索引。
BTREE索引(没有特殊指定的情况下)
频繁删改的字段,不适合建索引。
2)、优势
提高数据检索的效率,降低数据库的io成本
通过索引列对数据进行 排序,降低数据排序的成本,降低了cpu的消耗
3)、劣势
索引也是一张表,占磁盘空间。
更新表时要维护索引,会降更新效率。
索引只是一个提高效率的因素,建立索引需要花时间和精力。
4)、单值索引,只包含一个列,一张表可以有多个单值索引。
5)、唯一索引,索引列的值必须唯一,允许为空。
6)、复合索引,包含多个列。
7)、索引的相关操作
create index idx_user_name on user(name)
alter user add index idx_user_name on (name)
show index from user
drop index idx_user_name on user
8)、索引结构
Hash索引
full-text全文索引
R-Tree 索引
BTree索引 :
6、哪些情况要创建索引。
1)、主建自动建立唯一索引
2)、频繁作为查询条件的字段应该创建索引
3)、查询中与其他表关联的字段,外建关系建立索引。
4)、频繁更新的字段,不适合创建索引
5)、where条件里用不到的字段补创建索引。
6)、单建或者组合索引的选择问题,在高并发下倾向于创建复合索引
7)、查询中排序的字段,排序的字段如果按照索引去访问,将提高效率
8)、查询中统计或者分组字段
7、哪些情况不需要创建索引
1)、表记录太少
2)、经常增删的表
3)、数据重复且分布平均的字段。
8、性能分析:
mysql query optimizer
常见瓶颈:
cpu负担重:一般发生在数据装入内存和磁盘重读取数据的时候。
io负担重:装入数据远远大于内存容量时。
服务器硬件的性能瓶颈
explain:执行计划
怎么玩:explain+SQL
能干嘛:
1)能够查看表的读取顺序。
2)数据读取操作的操作类型。
3)哪些索引可以使用,
4)哪些索引被实际使用
5)表之间的引用
6)每张表有多少行被优化器查询。
explain+SQL的执行结果的头部
id:相同:则查询的顺序一样,为table中的从上到下。
如果id不同:id越大,则比较先查询。
derived2:表示衍生的虚表,其中2表示id为2的那张表。
select_type:主查询或者子查询或者简单查询
simple:不包含子查询或者union查询
primary、subquery、derived(临时)、union、
union-result 合并的结果集
table:显示关于哪张表
type:访问类型
system>const>eq_ref> ref> range>index>all
一般来说,得保证查询至少带到range级别,最好能达到ref.
system:表只有一行记录(等于系统表)。
const:表示通过检索一次就找到了,const用于
比较主建或者唯一索引,将查询放入where查询。
eq_ref:唯一性索引扫描,对于每个索引建,表中只有一条记录
与之匹配。常用与主建或者唯一索引的扫描。
ref:非唯一性索引扫描,会返回某个单独值的所有行。
range:只检索给定的范围。一般时where语句中加了
between and < >等范围的限制。
index:也是全表扫描,只不过是对索引的索引树进行扫描。
从索引中拿,而all从数据中拿。
all:全表扫描。
possible_keys:表中可能运用的索引,但不一定使用
key:实际使用的索引。若查询中使用了覆盖索引则该索引仅仅出现在
key列表中。
覆盖索引:建立的索引和查询的字段顺序和个数匹配。
key_len:索引字段的最大可能长度,并非实际使用长度。精度越大,则
长度越大。同样的结果下,key_len小好。
ref:在type为ref或者eq_ref级别时,所引用到的字段或者常量。
rows: 表中有多少被优化器查询。
extra:十分重要的而外信息。
using filesort:mysql无法用索引排序的排序为文件内排序。
已经建立了复合索引:idx_col1col2col3
(select col1 from t1 where col1='ac' order by col3)
using temporary:产生了临时表。常见了order by 或者
group by
(select col1 from t1 where col1 in('ac','ab') group by col3 )
正确:(select col2 from t1 where col1 in('ac','ab') group by col2,col3)
using index:使用了覆盖索引。如果有using where 表示用于查找,如果
没有则只用于从索引中读取数据。
覆盖索引:select的数据列只从索引中就能够取得,不必读取数据行。换句话说
就是查询列要被所建的索引覆盖。
using where:使用了where条件
using join buffer:使用了连接缓存。
impossible where:where 后面的语句总是为false。
select tables optimized away:在没有groupby的情况,基于索引优化min或者max操作。
distinct:优化distinct操作。找到第一个匹配的记录后就完成。
9、实际的案例知识总结:
1)建立复合索引后A_B_C,B字段范围以后的索引会失效,此时C进行了orderby的操作。
如果不合理,则删除索引。这次直接建立A_C索引,可以起作用。
2)两表之间的索引问题
左外连接要将索引建立在右表中,右外连接要将索引建立在左表中。
3)三表之间的问题
跟2)中一样,但是要注意:永远用小表驱动大表
优先优化内层的循环。
保证join条件已被索引。
10、索引失效问题
1)复合索引中全局匹配最好,也可以部分满足。
2)最佳左前缀法则
3)对索引的列不能进行操作,比如类型转换,函数处理等
4)范围之后的索引会失效
5)尽量使用覆盖索引,此时中间的某个索引如果使用范围的花化,type也为ref,key_len变小。(如果查询的字段被复合索引包含)
6)在使用不等于<>会使索引失效。
7)is null 或者is not null也无法使用索引
8)like 中如果开头为“%xxx",会导致索引失效,放在右边较好,但是type应该为range
如果硬是要两边加%怎么办:使用覆盖索引来解决。
9)字符串不加单引号,会使得索引失效。varchar类型不能失去单引号。
10)少用or,用它会使得索引失效。
11、建立了idx_abcd 则查询的时候,不管是a、b、c、d还是其他顺序,mysql会进行相关的优化。
select * from user where a=1 and b=1 and d=1 order by c(没有filesort)
(c也是用到了,但不是用于查询,而是用于排序,但没有统计到explain中)
select *from user where a=1 and b=1 order by d(这里排序是会出现file sort)
select *from user where a=1 and d=1 order by b,c(查询只用到一个索引,b、c用于排序,所以没有出现filesort)
select *from user where a=1 and d=1 order by c、b(出现了filesort)
select *from user where a=1 and b=1 and d=1 order by c、b(查询用到两个索引,order by c b=1),因为b=1是固定
的,所以不用进行排序。
select *from user where a=1 and d=1 group by c、b(分组之前必排序)出现filesort temporary(临时表)
select *from user where a=1 and b=1 and c like "1%" and d 用到所有
12、小表驱动大表
1)跑一天,查看查询状况,开启满查询日志,抓取对应的sql语句。
2)explain + sql
3) show profile(查看执行周期和细节)
4)mysql数据库的参数调优。
select *from a where id in (select id from b)
当b表小于a表时,用in要优于exists
select *from a exists (select 1 from where b.id=a.id)
13、使用order by
select *from a where age >20 order by age
不会出现filesort情况
select *from a where age > 20 order by birth
会出现filesort情况
select *from a where age > 20 order by brith,age
会出现filesort的情况
select *from a where age >20 order by age asc,birth desc
filesort: 单路排序:一次磁盘的扫描(现在某认的选项)sort_buffer中,如果不够,效率反而比较低和两路排序:对磁盘有两次扫描
oderby中三大方案:
避免使用select *(容易把sort_buffer_size用满)
如果超过了,会产生临时文件自行合并,导致多次io
尝试提高sort_buffer_size
尝试提高max_length_sort_data
orderby :后面要么全部升,要么全部降
order b y a = const order b ,c
order by a=const and b>const order by b,c(可以使用)
group by 是先排序再分组,where高于having,能在where中完成的就不要在having中
14、慢查询日志
慢查询日志是mysql提供的一种日志记录,超过long_query_time会被记录到日志中。默认为10秒
默认情况下,是没有开启的,需要手动开启。查看:show variables like "%slow_query_log%";
set global slow_query_log=1
show varables like "%slow_query%"
mysqldownslow是分析的一个工具。
15、批量插入
log_bin_trust_function_creator参数的开启
随即产生字符串的函数:
delimiter $$
create function random(n int) returns varchar(255)
begin
declare char_str varchar(100) default ''cjhcjhcjh;
return char_str;
end $$
存储过程:
16、show profile
可以用来分析当前语句执行的资源消耗情况。
show global varables like ""%profiling;
有三个属性:
query_id:查询的id
duration:持续的时间
query:查询的语句
show profile cpu,block io for query 3
对某条语句进行解析。如果出现:
converting heap to myisam:查询结果太大,内存不够
create temp table:创建临时表
copying temp to the disk:将临时表拷贝到硬盘中,危险
locked:出现锁的状况。
17、全局查询日志(只允许在测试环境中用)
show varables like "general_log";
set general_log=1;
set global log_output="table":以表的形式
则会把查询语句存入到mysql数据库的general_log表中,系统自带的数据库。、
18、mysql的锁:行锁、表锁(读锁、写锁)
show open tables(查看是否加了锁)
上锁:lock table a read,b write
unlock tables;解锁所有的表
加了读锁的表的session不可以写自己,不可以操作别人。(加了锁要清帐,才可以取操作其他的)
在别的session,可以读被锁的表和其他表,不可以写被锁的表,此时会处于阻塞状态。
加了写锁后,不可以操作其他表,可以对锁的表进行读和写
在别的session中只能操作其他表,对写锁的表,都处于阻塞状态。
show status like "table%"
table_locks_wait:锁等待的次数。
myisam 比较适合读为主的项目,写锁太多会造成阻塞。
行锁:
支持更高的并发量
innodb:支持事务,支持行锁。
事务的隔离级别:
读未提交
读已提交
可重复读
串行化
show variables like "%tx_isolation":
读己之所写,
强一致型(现实可能不太理想)c,高可用(a表示高可用)
某一行被update没有提交,本session可以看到更新;
其他session看不到更新,如果更新该行将会被阻塞。
当对应的session自动提交被禁止后,要想看到别的session的提交结果,要先commit下才可以看到
索引失效:会导致行锁变成表锁。
update user set username=100 where id=1;
则此时在另外一个session中该表会被锁主。
update tableA set name=2000(name为varchar类型,这样 会导致索引失效)
间隙锁:用范围的条件时,会对范围的记录上锁。尽管范围了没有某一条记录,也会加上锁。
会导致阻塞。
比如:update user set age=12 where id >1 and id <10
则另外一个session将无法对id为2到9的行进行操作,不管该行是否存在。
面试题目:锁定某一行
select * from user where id=8 for update;
show status like 'innodb_row_lock%';