丰富的线上&线下活动,深入探索云世界
做任务,得社区积分和周边
最真实的开发者用云体验
让每位学生受益于普惠算力
让创作激发创新
资深技术专家手把手带教
遇见技术追梦人
技术交流,直击现场
海量开发者使用工具、手册,免费下载
极速、全面、稳定、安全的开源镜像
开发手册、白皮书、案例集等实战精华
为开发者定制的Chrome浏览器插件
本文起源于有同学留言回复说想了解下MySQLDBA面试时可能涉及到的知识要点,那我们今天就来大概谈谈吧。
本文可以作为MySQLDBA面试官,以及候选人的双向参考:)
接下来先说下我以往在做MySQLDBA面试时的过程(套路):
基础知识,尤其是一些理论知识,例如:
通过考察候选人的基础知识掌握程度,可侧面反映候选人对学习的态度,是否仅浅层面的了解。
核心关键技术能力,例如:
通过考察候选人对这些核心关键技术的掌握程度,可知晓候选人对深层次知识的掌握情况,除了实践,理论方面掌握了多少。
发展潜力以及学习能力,例如:
这些知识对一般的DBA可能不太重要,但想要成为资深DBA或数据库架构师的话,这些知识是必不可少的。
先啰嗦说这么多吧,希望对有志成为DBA的同学有些帮助,加油加油。
1.请描述下MySQL中InnoDB支持的四种事务隔离级别名称,以及逐级之间区别
readuncommitted:未提交读。可以读取到其他线程修改(未提交)的数据
readcommitted:提交读。只能读取到其他线程已经提交的数据。解决脏读,修改的数据可能最后未提交。只锁定索引,并且不锁定索引前的间隙
repeatableread:可重复读。不能读取到其他线程提交的数据,间隙锁解决幻读。使用唯一索引进行等值查询,则只锁定索引,不锁定索取前间隙。其他查询,则不仅锁定索引,并且锁定索取范围包含的间隙
serializable:串行化读。所有的访问都串行化。将select转为select...lockinsharemode即为查询语句涉及到的数据加上共享琐,阻塞其他事务修改真实数据。
2.Mysql数据库有多少种日志
错误日志:记录出错信息,也记录一些警告信息或者正确的信息
二进制日志:记录对数据库执行更改的所有操作
查询日志:记录所有对数据库请求的信息,不论这些请求是否得到了正确的执行。
3.事务是如何通过日志来实现的
隔离性:通过锁实现
原子性、一致性和持久性是通过redo和undo来完成的。
在Innodb存储引擎中,事务日志是通过redo和innodb的存储引擎日志缓冲(Innodblogbuffer)来实现的,当开始一个事务的时候,会记录该事务的lsn(logsequencenumber)号;当事务执行时,会往InnoDB存储引擎的日志的日志缓存里面插入事务日志;当事务提交时,必须将存储引擎的日志缓冲写入磁盘(通过innodb_flush_log_at_trx_commit来控制),也就是写数据前,需要先写日志。这种方式称为“预写日志方式”,innodb通过此方式来保证事务的完整性。也就意味着磁盘上存储的数据页和内存缓冲池上面的页是不同步的,是先写入redolog,然后写入datafile,因此是一种异步的方式。通过showengineinnodbstatus/G来观察之间的差距
4.mysqldump以及xtranbackup的实现原理,
mysqldump是最简单的逻辑备份方式。在备份myisam表的时候,如果要得到一致的数据,就需要锁表,简单而粗暴。而在备份innodb表的时候,加上–master-data=1–single-transaction选项,在事务开始时刻,记录下binlogpos点,然后利用mvcc来获取一致的数据,由于是一个长事务,在写入和更新量很大的数据库上,将产生非常多的undo,显著影响性能,所以要慎用。
优点:简单,可针对单表备份,在全量导出表结构的时候尤其有用。
缺点:简单粗暴,单线程,备份慢而且恢复慢,跨IDC有可能遇到时区问题
xtrabackup它实际上是物理备份+逻辑备份的组合。在备份innodb表的时候,它拷贝ibd文件,并一刻不停的监视redolog的变化,append到自己的事务日志文件。在拷贝ibd文件过程中,ibd文件本身可能被写”花”,这都不是问题,因为在拷贝完成后的第一个prepare阶段,Xtrabackup采用类似于innodb崩溃恢复的方法,把数据文件恢复到与日志文件一致的状态,并把未提交的事务回滚。如果同时需要备份myisam表以及innodb表结构等文件,那么就需要用flushtableswithlock来获得全局锁,开始拷贝这些不再变化的文件,同时获得binlog位置,拷贝结束后释放锁,也停止对redolog的监视。
作为DBA,特别是Mysql的DBA,需要了解很多方面的内容,架构,性能,分析,代码等等。有时候一个人不可能面面俱到,特别是在面试的时候,面试官的喜好就能决定面试的结果,所以在面试之前多方面了解一下,以备不时之需。
MYSQL数据库服务器性能分析的方法命令有哪些
MYSQL数据库索引类型都有哪些
mysql有关权限的表都有哪几个
MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些权限表分别user,db,table_priv,columns_priv和host。下面分别介绍一下这些表的结构和内容:
mysql中myisam与innodb的区别
世界上没有最快的刀,也没有最结实的盾。所谓无坚不破,估计说的也是临时磨刀,不快也亮。就像面试一样,先能过去面试,才能谈及薪水。加油吧兄弟姐妹们!
Mysql面试题集
1.mysql的复制原理以及流程
MySQL的复制原理:Master上面事务提交时会将该事务的binlogevent写入
binlogfile,然后master将binlogevent传到slave上面,slave应用该binlogevent实现逻辑复制。
MySQL的复制是基于如下3个线程的交互(多线程复制里面应该是4类线程):
a.Master上面的binlogdump线程,该线程负责将master的binlogevent传到
slave;
b.Slave上面的IO线程,该线程负责接收Master传过来的binlog,并写入relay
log;
c.Slave上面的SQL线程,该线程负责读取relaylog并执行;
d.如果是多线程复制,无论是5.6库级别的假多线程还是MariaDB或者5.7的真
正的多线程复制,SQL线程只做coordinator,只负责把relaylog中的binlog
读出来然后交给worker线程,woker线程负责具体binlogevent的执行;
一致性可以从以下几个方面来讲:
a.在MySQL5.5以及之前,slave的SQL线程执行的relaylog的位置只能保存
在文件(relay-log.info)里面,并且该文件默认每执行10000次事务做一次
同步到磁盘,这意味着slave意外crash重启时,SQL线程执行到的位置和
数据库的数据是不一致的,将导致复制报错,如果不重搭复制,则有可能会
导致数据不一致。MySQL5.6引入参数relay_log_info_repository,将该参
数设置为TABLE时,MySQL将SQL线程执行到的位置存到
mysql.slave_relay_log_info表,这样更新该表的位置和SQL线程执行的用
户事务绑定成一个事务,这样slave意外宕机后,slave通过innodb的崩溃
恢复可以把SQL线程执行到的位置和用户事务恢复到一致性的状态。
b.MySQL5.6引入GTID复制,每个GTID对应的事务在每个实例上面最多执行
一次,这极大地提高了复制的数据一致性;
c.MySQL5.5引入半同步复制,用户安装半同步复制插件并且开启参数后,设
提交事务时不会返回,直到超时后切成异步复制,但是如果切成异步之前用
户线程提交时在master上面等待的时候,事务已经提交,该事务对master
上面的其他session是可见的,如果这时master宕机,那么到slave上面该
事务又不可见了,该问题直到5.7才解决;
d.MySQL5.7引入无损半同步复制,引入参rpl_semi_sync_master_wait_point,
该参数默认为after_sync,指的是在切成半同步之前,事务不提交,而是接
收到slave的ACK确认之后才提交该事务,从此,复制真正可以做到无损
的了。
延时性:
可以讲下5.5是单线程复制,5.6是多库复制(对于单库或者单表的并发操作是
没用的),5.7是真正意义的多线程复制,它的原理是基于groupcommit,只要
master上面的事务是groupcommit的,那slave上面也可以通过多个worker
线程去并发执行。和MairaDB10.0.0.5引入多线程复制的原理基本一样。
没碰到就说没有吧
2.mysql中varchar与char的区别以及varchar(20)中的20代表的涵义
在单字节字符集下,char(N)在内部存储的时候总是定长,而且没有变长
字段长度列表中。在多字节字符集下面,char(N)如果存储的字节数超过N,
那么char(N)将和varchar(N)没有区别。在多字节字符集下面,如果存
储的字节数少于N,那么存储N个字节,后面补空格,补到N字节长度。都
存储变长的数据和变长字段长度列表。varchar(N)无论是什么字节字符集,都
是变长的,即都存储变长数据和变长字段长度列表。
不影响内部存储,只是影响带zerofill定义的int时,前面补多少个0,易于报
表展示
3.innodb的事务与日志的实现方式
(1)有多少种日志
redo/undo
(2)日志的存放形式
redo:在页修改的时候,先写到redologbuffer里面,然后写到redolog的文件系
统缓存里面(fwrite),然后再同步到磁盘文件(fsync)。
Undo:在MySQL5.5之前,undo只能存放在ibdata*文件里面,5.6之后,可以通
过设置innodb_undo_tablespaces参数把undolog存放在ibdata*之外。
(3)事务是如何通过日志来实现的。
基本流程如下:
因为事务在修改页时,要先记undo,在记undo之前要记undo的redo,然后修改
数据页,再记数据页修改的redo。Redo(里面包括undo的修改)一定要比数据页
先持久化到磁盘。当事务需要回滚时,因为有undo,可以把数据页回滚到前镜像的
状态,崩溃恢复时,如果redolog中事务没有对应的commit记录,那么需要用undo
把该事务的修改回滚到事务开始之前。如果有commit记录,就用redo前滚到该事
务完成时并提交掉
4.mysql数据库cpu飙升到500%的话他怎么处理
当cpu飙升到500%时,先用操作系统命令top命令观察是不是mysqld占用导致的,如果不
看里面跑的session情况,是不是有消耗资源的sql在运行。找出消耗高的sql,看看执行
计划是否准确,index是否缺失,或者实在是数据量太大造成。一般来说,肯定要kill掉
这些线程(同时观察cpu使用率是否下降),等进行相应的调整(比如说加索引、改sql、改
内存参数)之后,再重新跑这些SQL。也有可能是每个sql消耗资源并不多,但是突然之间,
有大量的session连进来导致cpu飙升,这种情况就需要跟应用一起来分析为何连接数会激增,再做出相应的调整,比如说限制连接数等
explain出来的各种item的意义
profile的意义以及使用场景。
explain中的索引问题。
(1)explain出来的各种item的意义
id:每个被独立执行的操作的标志,表示对象被操作的顺序。一般来说,id值大,先被执行;
如果id值相同,则顺序从上到下。
select_type:查询中每个select子句的类型。具体待明天补充。
table:名字,被操作的对象名称,通常的表名(或者别名),但是也有其他格式。
partitions:匹配的分区信息。
type:join类型。具体指待明天补充。
possible_keys:列出可能会用到的索引。
key:实际用到的索引。
key_len:用到的索引键的平均长度,单位为字节。
ref:表示本行被操作的对象的参照对象,可能是一个常量用const表示,也可能是其他表的
key指向的对象,比如说驱动表的连接列。
rows:估计每次需要扫描的行数。
filtered:rows*filtered/100表示该步骤最后得到的行数(估计值)。
extra:重要的补充信息。具体待明天补充。
(2)profile的意义以及使用场景。
Profile用来分析sql性能的消耗分布情况。当用explain无法解决慢SQL的时候,需要用
的性能瓶颈。(我用的也不多,期待更好的答案)
(3)explain中的索引问题。
Explain结果中,一般来说,要看到尽量用index(type为const、ref等,key列有值),避
免使用全表扫描(type显式为ALL)。比如说有where条件且选择性不错的列,需要建立索引。
被驱动表的连接列,也需要建立索引。被驱动表的连接列也可能会跟where条件列一起建立
联合索引。当有排序或者groupby的需求时,也可以考虑建立索引来达到直接排序和汇总
的需求
备份计划
备份恢复失败如何处理
原理:
mysqldump属于逻辑备份。加入--single-transaction选项可以进行一致性备份。后台进程
会先设置session的事务隔离级别为RR(SETSESSIONTRANSACTIONISOLATIONLEVEL
REPEATABLEREAD),之后显式开启一个事务(STARTTRANSACTION/*!40100WITHCONSISTENT
SNAPSHOT*/),这样就保证了该事务里读到的数据都是事务事务时候的快照。之后再把表的
数据读取出来。如果加上--master-data=1的话,在刚开始的时候还会加一个数据库的读锁
(FLUSHTABLESWITHREADLOCK),等开启事务后,再记录下数据库此时binlog的位置(show
masterstatus),马上解锁,再读取表的数据。等所有的数据都已经导完,就可以结束事务。
Xtrabackup:
xtrabackup属于物理备份,直接拷贝表空间文件,同时不断扫描产生的redo日志并保存下
来。最后完成innodb的备份后,会做一个flushenginelogs的操作(老版本在有bug,在
5.6上不做此操作会丢数据),确保所有的redolog都已经落盘(涉及到事务的两阶段提交
概念,因为xtrabackup并不拷贝binlog,所以必须保证所有的redolog都落盘,否则可
情)。然后还需要flushtableswithreadlock,把myisam等其他引擎的表给备份出来,
备份完后解锁。这样就做到了完美的热备。
备份计划:
视库的大小来定,一般来说100G内的库,可以考虑使用mysqldump来做,因为mysqldump
出来的文件比较小,压缩之后更小)。
100G以上的库,可以考虑用xtranbackup来做,备份速度明显要比mysqldump要快。一般
物理备份恢复快,逻辑备份恢复慢
备份恢复失败如何处理:
首先在恢复之前就应该做足准备工作,避免恢复的时候出错。比如说备份之后的有效性检查、
权限检查、空间检查等。如果万一报错,再根据报错的提示来进行相应的调整。、
可以使用批量ssh工具pssh来对需要重启的机器执行重启命令。也可以使用salt(前提是客户端有安装salt)或者ansible(ansible只需要ssh免登通了就行)等多线程工具同时操作多台服务器
4.innodb的读写参数优化
读取参数,globalbufferpool以及localbuffer
写入参数
缓存参数以及缓存的适用场景
(1)读取参数,globalbufferpool以及localbuffer
Globalbuffer:
Innodb_buffer_pool_size
innodb_log_buffer_size
innodb_additional_mem_pool_size
localbuffer(下面的都是server层的session变量,不是innodb的):
Read_buffer_size
Join_buffer_size
Sort_buffer_size
Key_buffer_size
Binlog_cache_size
(2)写入参数
insert_buffer_size资源由www.eimhe.com美河学习在线收集提供
innodb_double_write
innodb_write_io_thread
innodb_flush_method
Sync_binlog
Innodb_flush_log_at_trx_commit
Innodb_lru_scan_depth
Innodb_io_capacity
Innodb_io_capacity_max
innodb_max_dirty_pages_pct
(4)缓存参数以及缓存的适用场景
指的是查询缓存吗???使用于读多写少,如分析报表等等
query_cache_size
query_cache_type
query_cache_limit
maximumquery_cache_size
作为DBA,不懂开发可以,不懂优化可以么?估计大部分是不可以的。因为开发的问题真的太多啦,多到你自己都觉得绝望!优化是个大大的标题,涉及到方方面面,主机,网络,SQL语句,不管你做了多久的DBA,有些东西还是得知道一点。
例题:SELECT*FROM`bigdata`ORDERBYidDESCLIMIT100000,2000;
耗时:0.813ms
如何对上述语句在高并发的情况下进行优化?
答案:
利用clue方法,给翻页提供一些线索,比如还是SELECT*FROM`bigdata`orderbyiddesc,按id降序分页,每页2000条,当前是第50页,当前页条目id最大的是102000,最小的是100000。如果我们只提供上一页、下一页这样的跳转(不提供到第N页的跳转)。
那么在处理上一页的时候SQL语句可以是:
SELECT*FROM`bigdata`WHEREid<=102000ORDERBYidDESCLIMIT2000;#上一页
耗时:0.015ms
处理下一页的时候SQL语句可以是:
SELECT*FROM`bigdata`WHEREid>102000ORDERBYidASCLIMIT2000;#下一页
2.Mysql语句explain的含义:
mysql>explainSELECT*FROM`bigdata`WHEREto_id=6696ANDdel=0ANDbigdata=0ORDERBY`send_time`DESCLIMIT4;
+—-+————-+———+——+—————+——-+———+——-+——+—————————–+
|id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|
|1|SIMPLE|bigdata|ref|to_id|to_id|4|const|1|Usingwhere;Usingfilesort|
1rowinset(0.00sec)
table显示这一行的数据是关于哪张表的
type这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL
key实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,可以在SELECT语句中使用USEINDEX(indexname)来强制使用一个索引或者用IGNOREINDEX(indexname)来强制MYSQL忽略索引
key_len使用的索引的长度。在不损失精确性的情况下,长度越短越好
ref显示索引的哪一列被使用了,如果可能的话,是一个常数
rowsMYSQL认为必须检查的用来返回请求数据的行数
Extra关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这里可以看到的坏的例子是Usingtemporary和Usingfilesort,意思MYSQL根本不能使用索引,结果是检索会很慢
extra列返回的描述的意义
Distinct一旦MYSQL找到了与行相联合匹配的行,就不再搜索了
NotexistsMYSQL优化了LEFTJOIN,一旦它找到了匹配LEFTJOIN标准的行,就不再搜索了
Rangecheckedforeach
Record(indexmap:#)没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一
Usingfilesort看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行
Usingindex列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候
Usingtemporary看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDERBY上,而不是GROUPBY上
Whereused使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题
不同连接类型的解释(按照效率高低的顺序排序)
system表只有一行:system表。这是const连接类型的特殊情况
const表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为MYSQL先读这个值然后把它当做常数来对待
eq_ref在连接中,MYSQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用
ref这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好
range这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西时发生的情况
index这个连接类型对前面的表中的每一个记录联合进行完全扫描(比ALL更好,因为索引一般小于表数据)
ALL这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免
3.举例说明mysql常用的hint
强制索引FORCEINDEX
SELECT*FROMTABLE1FORCEINDEX(FIELD1)…
以上的SQL语句只使用建立在FIELD1上的索引,而不使用其它字段上的索引。
忽略索引IGNOREINDEX
SELECT*FROMTABLE1IGNOREINDEX(FIELD1,FIELD2)…
在上面的SQL语句中,TABLE1表中FIELD1和FIELD2上的索引不被使用。
关闭查询缓冲SQL_NO_CACHE
SELECTSQL_NO_CACHEfield1,field2FROMTABLE1;
有一些SQL语句需要实时地查询数据,或者并不经常使用(可能一天就执行一两次),这样就需要把缓冲关了,不管这条SQL语句是否被执行过,服务器都不会在缓冲区中查找,每次都会执行它。
强制查询缓冲SQL_CACHE
SELECTSQL_CALHE*FROMTABLE1;
如果在my.ini中的query_cache_type设成2,这样只有在使用了SQL_CACHE后,才使用查询缓冲。
优先操作HIGH_PRIORITY
HIGH_PRIORITY可以使用在select和insert操作中,让MYSQL知道,这个操作优先进行。
SELECTHIGH_PRIORITY*FROMTABLE1;
滞后操作LOW_PRIORITY
LOW_PRIORITY可以使用在insert和update操作中,让mysql知道,这个操作滞后。
updateLOW_PRIORITYtable1setfield1=wherefield1=…
延时插入INSERTDELAYED
INSERTDELAYEDINTOtable1setfield1=…
INSERTDELAYEDINTO,是客户端提交数据给MySQL,MySQL返回OK状态给客户端。而这是并不是已经将数据插入表,而是存储在内存里面等待排队。当mysql有空余时,再插入。另一个重要的好处是,来自许多客户端的插入被集中在一起,并被编写入一个块。这比执行许多独立的插入要快很多。坏处是,不能返回自动递增的ID,以及系统崩溃时,MySQL还没有来得及插入数据的话,这些数据将会丢失。
强制连接顺序STRAIGHT_JOIN
SELECTTABLE1.FIELD1,TABLE2.FIELD2FROMTABLE1STRAIGHT_JOINTABLE2WHERE…
由上面的SQL语句可知,通过STRAIGHT_JOIN强迫MySQL按TABLE1、TABLE2的顺序连接表。如果你认为按自己的顺序比MySQL推荐的顺序进行连接的效率高的话,就可以通过STRAIGHT_JOIN来确定连接顺序。
强制使用临时表SQL_BUFFER_RESULT
SELECTSQL_BUFFER_RESULT*FROMTABLE1WHERE…
分组使用临时表SQL_BIG_RESULT和SQL_SMALL_RESULT
SELECTSQL_BUFFER_RESULTFIELD1,COUNT(*)FROMTABLE1GROUPBYFIELD1;
一般用于分组或DISTINCT关键字,这个选项通知MySQL,如果有必要,就将查询结果放到临时表中,甚至在临时表中进行排序。SQL_SMALL_RESULT比起SQL_BIG_RESULT差不多,很少使用。
4.举例说明如何对mysql索引优化
创建索引
对于查询占主要的应用来说,索引显得尤为重要。很多时候性能问题很简单的就是因为我们忘了添加索引而造成的,或者说没有添加更为有效的索引导致。如果不加索引的话,那么查找任何哪怕只是一条特定的数据都会进行一次全表扫描,如果一张表的数据量很大而符合条件的结果又很少,那么不加索引会引起致命的性能下降。但是也不是什么情况都非得建索引不可,比如性别可能就只有两个值,建索引不仅没什么优势,还会影响到更新速度,这被称为过度索引。
复合索引
比如有一条语句是这样的:select*fromuserswherearea=’beijing’andage=22;
如果我们是在area和age上分别创建单个索引的话,由于mysql查询每次只能使用一个索引,所以虽然这样已经相对不做索引时全表扫描提高了很多效率,但是如果在area、age两列上创建复合索引的话将带来更高的效率。如果我们创建了(area,age,salary)的复合索引,那么其实相当于创建了(area,age,salary)、(area,age)、(area)三个索引,这被称为最佳左前缀特性。因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。
索引不会包含有NULL值的列
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。
使用短索引
对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
排序的索引问题
mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么orderby中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
like语句操作
一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like“%aaa%”不会使用索引而like“aaa%”可以使用索引。
不要在列上进行运算
select*fromuserswhereYEAR(adddate)<2007;
将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成
select*fromuserswhereadddate<‘2007-01-01’;
不使用NOTIN和操作
NOTIN和操作都不会使用索引将进行全表扫描。NOTIN可以NOTEXISTS代替,id3则可使用id>3orid<3来代替。
drop直接删掉表truncate删除表中数据,再插入时自增长id又从1开始delete删除表中数据,可以加where字句。
DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。TRUNCATETABLE则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。
表和索引所占空间。当表被TRUNCATE后,这个表和索引所占用的空间会恢复到初始大小,而DELETE操作不会减少表或索引所占用的空间。drop语句将表所占用的空间全释放掉。
一般而言,drop>truncate>delete
应用范围。TRUNCATE只能对TABLE;DELETE可以是table和view
TRUNCATE和DELETE只删除数据,而DROP则删除整个表(结构和数据)。
truncate与不带where的delete:只删除数据,而不删除表的结构(定义)drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。
delete语句为DML(datamaintainLanguage),这个操作会被放到rollbacksegment中,事务提交后才生效。如果有相应的tigger,执行的时候将被触发。
truncate、drop是DLL(datadefinelanguage),操作立即生效,原数据不放到rollbacksegment中,不能回滚
在没有备份情况下,谨慎使用drop与truncate。要删除部分数据行采用delete且注意结合where来约束影响范围。回滚段要足够大。要删除表用drop;若想保留表而将表中数据删除,如果于事务无关,用truncate即可实现。如果和事务有关,或老师想触发trigger,还是用delete。
Truncatetable表名速度快,而且效率高,因为:
truncatetable在功能上与不带WHERE子句的DELETE语句相同:二者均删除表中的全部行。但TRUNCATETABLE比DELETE速度快,且使用的系统和事务日志资源少。DELETE语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATETABLE通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。
TRUNCATETABLE删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用DELETE。如果要删除表定义及其数据,请使用DROPTABLE语句。
对于由FOREIGNKEY约束引用的表,不能使用TRUNCATETABLE,而应使用不带WHERE子句的DELETE语句。由于TRUNCATETABLE不记录在日志中,所以它不能激活触发器。
2.存储过程与触发器的区别
3.一张表,里面有ID自增主键,当insert了10条记录之后,删除了第10,9,8条记录,再把Mysql重启,再insert一条记录,这条记录的ID是11还是8
==>此问题答案在留言10条后发布
4.MySQL的联结含义及用法
内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结。
外联结:分为外左联结和外右联结。
左联结A、B表的意思就是将表A中的全部记录和表B中联结的字段与表A的联结字段符合联结条件的那些记录形成的记录集的联结,这里注意的是最后出来的记录集会包括表A的全部记录。
n右联结A、B表的结果和左联结B、A的结果是一样的,也就是说:
lSelectA.nameB.nameFromALeftJoinBOnA.id=B.id和SelectA.nameB.nameFromBRightJoinAonB.id=A.id执行后的结果是一样的。
全联结:将两个表中存在联结关系的字段的所有记录取出形成记录集的联结(这个不需要记忆,只要是查询中提到了的表的字段都会取出,无论是否符合联结条件,因此意义不大)。
无联结:不用解释了吧,就是没有使用联结功能呗,也有自联结的说法。
答:下面的语句的结果会显示服务器的版本和当前的数据库名称
mysql>SELECTVERSION(),DATABASE();+-------------------------+------------+|VERSION()|DATABASE()|+-------------------------+------------+|5.5.34-0ubuntu0.13.10.1|NULL|+-------------------------+------------+1rowinset(0.06sec)在Database一列中显示NULL是因为我们当前没有选择任何数据库。因此,使用下面的语句先选择一个数据库,就能看到相应的结果。
mysql>useTecmint;ReadingtableinformationforcompletionoftableandcolumnnamesYoucanturnoffthisfeaturetogetaquickerstartupwith-ADatabasechangedmysql>selectVERSION(),DATABASE();+-------------------------+------------+|VERSION()|DATABASE()|+-------------------------+------------+|5.5.34-0ubuntu0.13.10.1|tecmint|+-------------------------+------------+1rowinset(0.00sec)2.使用非运算符(!)从表”Tecmint”中列出除了”SAM”以外的所有user记录答:使用下面的语句
mysql>SELECT*FROMTecmintWHEREuser!=SAM;+---------------------+---------+---------+---------+---------+-------+|date|user|host|root|local|size|+---------------------+---------+---------+---------+---------+-------+|2001-05-1414:42:21|Anthony|venus|barb|venus|98151||2001-05-1508:50:57|TIM|venus|phil|venus|978|+---------------------+---------+---------+---------+---------+-------+3.‘AND’运算符有可能带着非运算符(!)一起用吗?答:当我们使用‘=’号时用‘AND’连接,用‘!=’时用‘OR’连接,下面是‘=’和AND运算符一起用的例子
mysql>SELECT*FROMmailWHEREuser=SAMANDroot=phil‘!=’和OR运算符的例子
mysql>SELECT*FROMmailWHEREuser!=SAMORroot!=phil+---------------------+---------+---------+---------+---------+-------+|date|user|host|root|local|size|+---------------------+---------+---------+---------+---------+-------+|2001-05-1414:42:21|Anthony|venus|barb|venus|98151|+---------------------+---------+---------+---------+---------+-------+AND和OR在MySQL中被看作连接运算符
答:使用IFNULL()方法能使MySQL中的查询更加精确。IFNULL()方法将会测试它的第一个参数,若不为NULL则返回该参数的值,否则返回第二个参数的值
mysql>SELECTname,IFNULL(id,'Unknown')AS'id'FROMtaxpayer;+---------+---------+|name|id|+---------+---------+|bernina|198-48||bertha|Unknown||ben|Unknown||bill|475-83|+---------+---------+5.如果你只想知道从一个结果集的开头或者结尾开始的特定几条记录,该如何实现?答:我们需要把LIMIT语句接在ORDERBY语句后使用,以达到上述效果。
答:在MySQL中获取当前日期就是如下的SELECT语句这么简单。
mysql>SELECTCURRENT_DATE();+----------------+|CURRENT_DATE()|+----------------+|2014-06-17|+----------------+8.MySQL中如何将表导出为XML文件答:我们可以使用’-e’(export)选项来把MySQL表或整个数据库导出到XML文件。当处理大型表的时候我们可能需要手动导出,不过对于小表的话可以直接使用想phpMyAdmin等这样的工具。
mysql-uUSER_NAME-xml-e'SELECT*FROMtable_name'>table_name.xml上面的例子中USER_NAME是数据库的用户名,table_name是待导出为xml文件的表名,table_name.xml是存放数据的xml文件
答:MySQL_pconnect()打开一个持久的数据库连接,这意味着数据库不是在每次页面加载的时候被打开一个新连接,因此我们不能使用MySQL_close()来关闭一个持久的连接。
MySQL_pconnect和MySQL_connect最简要的区别是:
与MySQL_pconnect不同,MySQL_connect在每次页面被加载的时候打开连接,这个连接可以使用MySQL_close()语句来关闭。
答:下面的命令将会显示出‘user’表中所有的索引
mysql>showindexfromuser;+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+|Table|Non_unique|Key_name|Seq_in_index|Column_name|Collation|Cardinality|Sub_part|Packed|Null|Index_type|Comment|Index_comment|+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+|user|0|PRIMARY|1|Host|A|NULL|NULL|NULL||BTREE||||user|0|PRIMARY|2|User|A|4|NULL|NULL||BTREE|||+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+2rowsinset(0.00sec)11.什么是CSV表答:CSV是逗号分隔值(Comma-SeparatedValues)或也被称为字符分隔值(Character-SeparatedValues)的缩写。CSV表以纯文本和表格形式来存储数据。
1、MySQL的复制原理以及流程
基本原理流程,3个线程以及之间的关联;
1.主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中;
2.从:io线程——在使用startslave之后,负责从master上拉取binlog内容,放进自己的relaylog中;
3.从:sql执行线程——执行relaylog中的语句;
2、MySQL中myisam与innodb的区别,至少5点
(1)、问5点不同;
1>.InnoDB支持事物,而MyISAM不支持事物
2>.InnoDB支持行级锁,而MyISAM支持表级锁
3>.InnoDB支持MVCC,而MyISAM不支持
4>.InnoDB支持外键,而MyISAM不支持
5>.InnoDB不支持全文索引,而MyISAM支持。
(2)、innodb引擎的4大特性
插入缓冲(insertbuffer),二次写(doublewrite),自适应哈希索引(ahi),预读(readahead)
(3)、2者selectcount(*)哪个更快,为什么
myisam更快,因为myisam内部维护了一个计数器,可以直接调取。
.
一、sql语句应该考虑哪些安全性?
(1)索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。(2)普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。(3)普通索引允许被索引的数据列包含重复的值,如果能确定某个数据列只包含彼此各不相同的值,在为这个数据索引创建索引的时候就应该用关键字UNIQE把它定义为一个唯一所以,唯一索引可以保证数据记录的唯一性。(4)主键,一种特殊的唯一索引,在一张表中只能定义一个主键索引,逐渐用于唯一标识一条记录,是用关键字PRIMARYKEY来创建。(5)索引可以覆盖多个数据列,如像INDEX索引,这就是联合索引。(6)索引可以极大的提高数据的查询速度,但是会降低插入删除更新表的速度,因为在执行这些写操作时,还要操作索引文件。
三、一张表,里面有ID自增主键,当insert了17条记录之后,删除了第15,16,17条记录,再把Mysql重启,再insert一条记录,这条记录的ID是18还是15?
(1)如果表的类型是MyISAM,那么是18。因为MyISAM表会把自增主键的最大ID记录到数据文件里,重启MySQL自增主键的最大ID也不会丢失。(2)如果表的类型是InnoDB,那么是15。InnoDB表只是把自增主键的最大ID记录到内存中,所以重启数据库或者是对表进行OPTIMIZE操作,都会导致最大ID丢失。
四、请简述项目中优化sql语句执行效率的方法,从哪些方面。sql语句性能如何分析?
(1)尽量选择较小的列(2)将where中用的比较频繁的字段建立索引(3)select子句中避免使用‘*’(4)避免在索引列上使用计算,not,in和<>等操作(5)当只需要一行数据的时候使用limit1(6)保证表单数据不超过200w,适时分割表(7)针对查询较慢的语句,可以使用explain来分析该语句具体的执行情况
五、mysql_fetch_row()和mysql_fetch_array()的区别
这两个函数,返回的都是一个数组,区别就是第一个函数返回的数组是只包含值,我们只能row[0],row[1],这样以数组下标来读取数据,而mysql_fetch_array()返回的数组既包含第一种,也包含键值对的形式,我们可以这样读取数据,(假如数据库的字段是username,passwd):row[‘username‘],row[‘passwd‘。
1.MYISAM和INNODB的不同?答:主要有以下几点区别:a)构造上的区别MyISAM在磁盘上存储成三个文件,其中.frm文件存储表定义;.MYD(MYData)为数据文件;.MYI(MYIndex)为索引文件。而innodb是由.frm文件、表空间(分为独立表空间或者共享表空间)和日志文件(redolog)组成。b)事务上的区别myisam不支持事务;而innodb支持事务。c)锁上的区别myisam使用的是表锁;而innodb使用的行锁(当然innodb也支持表锁)。表级锁:直接锁定整张表,在锁定期间,其他进程无法对该表进行写操作,如果设置的是写锁,那么其他进程读也不允许,因此myisam支持的并发量低,但myisam不会出现死锁;行级锁:只对指定的行进行锁定,其他进程还是可以对表中的其他行进行操作的。因此行锁能大大的减少数据库操作的冲突,但有时会导致死锁。d)是否支持外键的区别myisam不支持外键,innodb支持外键e)selectcount(*)的区别对于没有where的count(*)使用MyISAM要比InnoDB快得多。因为MyISAM内置了一个计数器,count(*)时它直接从计数器中读,而InnoDB必须扫描全表。f)myisam只把索引都load到内存中,而innodb存储引擎是把数据和索引都load到内存中
2.公司现有的数据库架构,总共有几组mysql库?答:我们公司现在有两组MySQL。其中一套是生产库,一套是测试库。生产库和测试库都是用的mha+半同步复制做的高可用。我们所有的项目web前端量(大概有10个项目)指向的都是一个机器上的mysql实例。因为我们是传统行业,并发访问量并不是很大,所以目前我们的生产mysql数据库未出现性能问题。
3.如何提高insert的性能?答:有如下方法:a)合并多条insert为一条,即:insertintotvalues(a,b,c),(d,e,f),,,原因分析:主要原因是多条insert合并后日志量(MySQL的binlog和innodb的事务让日志)减少了,降低日志刷盘的数据量和频率,从而提高效率。通过合并SQL语句,同时也能减少SQL语句解析的次数,减少网络传输的IO。b)修改参数bulk_insert_buffer_size,调大批量插入的缓存;c)设置innodb_flush_log_at_trx_commit=0,相对于innodb_flush_log_at_trx_commit=1可以十分明显的提升导入速度;(备注:innodb_flush_log_at_trx_commit参数对InnoDBLog的写入性能有非常关键的影响。该参数可以设置为0,1,2,解释如下:0:logbuffer中的数据将以每秒一次的频率写入到logfile中,且同时会进行文件系统到磁盘的同步操作,但是每个事务的commit并不会触发任何logbuffer到logfile的刷新或者文件系统到磁盘的刷新操作;1:在每次事务提交的时候将logbuffer中的数据都会写入到logfile,同时也会触发文件系统到磁盘的同步;2:事务提交会触发logbuffer到logfile的刷新,但并不会触发磁盘文件系统到磁盘的同步。此外,每秒会有一次文件系统到磁盘同步操作。)
d)手动使用事务因为mysql默认是autocommit的,这样每插入一条数据,都会进行一次commit;所以,为了减少创建事务的消耗,我们可用手工使用事务,即STARTTRANSACTION;insert。。,insert。。commit;即执行多个insert后再一起提交;一般1000条insert提交一次。
5.有没有用GTID,对GTID了解吗?答:用过GTID。曾经民航局的一个项目就用的是GTID。GTID是mysql5.6的新东西,用事务提交号替换binlog的位置号。不过GTID这个东西在5.6还是有很多局限性的,个人不建议用。GTID的全称为globaltransactionidentifier,可以翻译为全局事务标示符。GTID由两部分组成:GTID=source_id:transaction_idsource_id用于标示源服务器,用server_uuid来表示,这个值在第一次启动时生成,并写入到配置文件data/auto.cnf中transaction_id则是根据在源服务器上第几个提交的事务来确定。
6.Innodb是行锁,那什么时候会产生行锁,什么情况下会变成表锁?答:一般情况下,innodb只对指定的行进行锁定,其他进程还是可以对表中的其他行进行操作的,因此,这时候innodb加的就是行锁;但是,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,例如updatetablesetnum=1wherenamelike“%aaa%”。
7.使用过其他分支版本的数据库吗?percona,mariadb等。对percona的pxc集群了解吗?
答:除了oracle旗下的MySQL外,我还使用过perconaserver。percona是在源生mysql的基础上,进行了优化和改进,所以percona的性能比mysql更好。目前,我知道percona提供免费的线程池功能,而社区版的mysql没有线程池的功能(当然,企业版的mysql是有线程池的,但是需要收费);另外percona还支持NUMA等功能。我熟悉pxc,我曾经在测试环境搭建过pxc,但是没有在生产上使用,因为目前使用pxc的企业不是很多,目前我知道搜狐在用pxc。pxc是摒弃mysql主从的概念,即对于pxc来说,每个节点都可以读写,并且写一份数据,其他节点会同时拥有,这是一种同步的复制方案(区别于Mysql主从的异步复制)
8.除了mysql,还了解过其他数据库吗?oracle,redis,mongodb等。
答:除了mysql,我还熟悉oracle,对oracle有两年的使用经验。不过,我对redis和mongodb没有接触过,如果工作需要,我会学习他们。
9.工作中遇到的最大的问题以及做的最好的工作?答:自由发挥
10.分库分表有没有用到,怎么实现的?
12.mysql的权限怎么管理?答:只给insert,update,select和delete四个权限即可。有时候delete都不给。
13.有开发基础吗?答:没有
14.如果发现CPU,或者IO压力很大,怎么定位问题?
>
><
<
<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>&&>>>>>>>>>>>>>>>>>>>