1. Mysql如何实现索引的?
B+树,hash所有,全文索引
2. Innodb和myisam索引实现的方式区别?
共同点:二者都是使用的B+树索引
Innodb:innodb的辅助索引(非主键索引、非聚簇索引)data域存储的是主键的值而不是地址,innodb数据文件本身就是主索引文件
Myisam:myisam的索引跟数据是分开存储的,索引文件仅保存记录所在页的指针(物理地址,通过读取页来读取索引行)
3. 如果一个新表中没有创建索引(主键也没有),那么还会创建B+树么?
会。当有主键索引的时候,B+树就生成了,当没有主键和其他索引的时候,MySQL会创建一个隐式的主键id(系统内部使用的id,实际上你不能拿来用),这个隐式id也是不会重复的,好处是合理的存储数据,让所有数据落到B+树的位置。
4. B+树中聚簇索引与非聚簇索引实现区别?
聚簇索引:主键为索引且唯一
实现:索引与数据保存在同一个B+树中,页内的记录按照主键大小排序形成一个单向链表,页与页之间根据页中记录主键大小排序成一个双向链表,非叶子节点存储的是记录的主键和页号,只有叶子节点存储的才是完整记录
优点:因为在同树中,不论是排序查找还是范围查找,访问磁盘的速度非常快,由于是有序排列,由于数据是紧密相连的,能节省磁盘大量的io交互。
缺点:数据写入速度严重依赖写入顺序,也就是按照主键顺序写入是最快的方式,不然会出现页分裂,严重影响性能,所以,innodb表一般都会定义自增为主键
非聚簇索引:非主键索引,如普通索引,联合索引,复合索引
实现:页内按照字段数据大小排序成一个单向链表,页与页之间也是按照该字段形成的双向链表,非叶子节点存储的是记录的字段跟页号,叶子节点存储的是该字段与主键值。当通过非聚簇索引B+树找到聚簇索引B+树的主键之后,再通过主键的B+树找到叶子节点的数据。整个过程会有两次查找
5. 聚簇索引与非聚簇索引查找数据逻辑(可以参考第五问)
举个例子:一张表3个字段,id为主键,name为普通索引,age。
一条数据 1,张三,20 。
select * from stu where id=1; 这条SQL查询会直接到聚簇索引B+树找到叶子节点id=1的完整数据
select * from stu where name=’张三’; 这条SQL查询是先到非聚簇索引B+树找到叶子节点中name对应的主键id,该处name对应的主键id=1,然后再到聚簇索引B+树找叶子节点主键id=1的完整数据
7. 一个3层B+树能存放多少条索引?
在默认是16k的情况下,最叶子节点每个16条*1600个最叶子节点*16叶子节点≈40960000
8. B+树索引中的CRUD执行效率是怎样的?
C:创建一般直接在树的最叶子节点后面新增,不会改变树形。当然如果数据量很大的话,是会改变树形的,也就是自旋,3层变成4层,总的来说还算是比较快。还有一种极端情况,就是最叶子节点只剩余1K了,但是数据还有2K未写进去,因为会创建新页,创建新页又会从跟节点从新走B+树
R:读取操作,根据左小右大,依次从根节点开始查找到最叶子节点的树数据,效率快
U:一般不更新id,树形是不变的,如果id改大(小),那最叶子节点对应的位置就会有所变化,也会比较消耗资源,所以不改id影响不会很大
D:删除操作,有可能导致空页情况,后面的页会“前移”填补空页,从新排成双向链表,整个数据前移,这是比较麻烦的
9. 自适应哈希索引是什么?
自适应哈希索引是MySQL系统内部给我们提供的一条额外的所有机制,由于是系统内部提供的机制,我们无法主动干预,可以通过show engine innodb status\G 看一下
10. 什么是23树,234树?
图解
23树
234树
11. 自增主键跟字符串主键的区别和影响?
前者:自增主键很好的维持底层数据顺序写入跟读取,因为是有序的,所以还支持范围查找
后者:对比上面,字符串是做不到的
12. 使用int自增主键,当前最大id值是10,删除9和10,再插入一条数据,此时添加的id是几?
删除两条数据之后,分两种情况
情况1:机器重启,会从当前最大id开始递增,也就是插入的数据是9
情况2:机器不重启,会延续之前的最大id,所以插入的值是11
13. 索引的优缺点?
优点
聚簇索引:顺序读写,并且支持有序的范围查找
非聚簇索引:查找数据需要回表进行二次查找。当多个条件都带有索引,并且索引能匹配上就不需要回表
缺点:会占用磁盘空间与消耗时间,尤其是大表创建索引
14. 索引一定能提升效率吗?
这个不是绝对的,查询的效率肯定是会提升,增删改可能会降低效率,因为会从新创建一颗索引B+树
15. 大文本内容的索引如何创建和优化?
法1:分表存储,比如两个表(一个表存少部分数据,一个表存文本数据)都建好索引,关联两表索引查出对应的文体
法2:使用es为大文本创建索引
比如:“大文本内容的索引如何创建和优化?”,这段文体在“大文本内容的”上建立索引,利用精确加模糊匹配:大文本%
16. 一个表中可以有多个(非)聚簇索引吗?
聚簇索引只能有一个,非聚簇索引可以有多个
17. 聚簇索引和非聚簇索引在CRUD的时候,区别是什么?
聚簇索引因为是有序唯一的,所以聚簇索引比非聚簇索引插入速度慢很多,查询速度快很多
非聚簇索引需要二次查找,第一次找主键,第二次根据主键找到行数据。此处还有一种情况,覆盖索引,select name from stu where name = ‘xxx’,条件上的索引覆盖前面查询的列,就会直接返回,不需要再拿到id进行二次查找
18. 非聚簇索引的最叶子节点为什么不存储数据地址,而是主键?
因为聚簇索引中有时会引发分页操作,重排操作,数据有可能会移动,如果记录的是地址,会记录错误的新数据
19. 什么是回表?
在非聚簇索引中查询出来id,再回表(聚簇索引)通过id找出完整的数据
20. 什么是覆盖索引?
条件已经包含你所查询的字段,此时查询出来的就是你要的数据,不需要进行回表。参考17问。select name from stu where name = ‘张%’
21. 非聚簇索引一定会回表查询吗?
不一定,当查询条件覆盖了查询字段就不需要进行回表查询
22. 为什么要回表查询?直接存储数据不行吗?
如果每创建一个索引,就会增加一颗b+树的存储,这样的话会很占用空间,其次当修改的时候,会有大量磁盘io开销。
23. 如果把innodb表的主键删掉,还能进行回表查询吗?
能,删掉主键后系统会自动生成一个隐式的id,后续的查询通过rowid辅助回表查询
24. 什么是联合索引、组合索引、复合索引?
b1,b2 -> index
b2,b1 -> index
多个字段创建一个索引。上面创建的两个索引树,并且底层最叶子节点存储是按照最左字段来建立的B+树(数字进行大小排序,字符串转换成ASCII排序)
拿第一条索引来说,如果条件 b1=xxx and b2=xxx;都能按照顺序匹配上,这个就是全值匹配,如果条件只有b2,那这个是不会走索引的(索引失效),因为该处(b1,b2 -> index)的联合索引是按照 b1建立的索引树。
25. 什么是唯一索引?
Unique index :字段列值唯一(允许有null,且无次数约定)
26. 唯一索引影响性能吗?
影响的,因为数据写入会先进行查询,没有匹配到才会把数据写入进去。但是大体来讲,唯一索引的insert 速度远小于select查询速度,这个是可以接受的
27. 什么时候创建唯一索引?
字段数据唯一的时候就需要,比如身份证号,手机号,学生表的学号
28. 索引在什么时候适合创建,什么时候不适合创建?
适合创建索引:频繁查询的字段,关联,排序,统计,分组等这些都可以
不适合创建索引:频繁更新的字段,表数据量少,参数mysql系统函数的字段,上述关联排序等用不上的字段
索引创建误解:认为只要是查询就创建索引、认为索引创建消耗磁盘空间以及拖慢更新速度就不建立索引,认为唯一索引很耗时就不创建
29. 索引下推是什么?
5.7版本之前是没有该功能的,5.7至现在8.x版本都有
未开启索引下推:根据筛选条件筛选一个条件返回结果集再回表筛选第二个条件返回结果集,以此类推
开启索引下推:查询时多个条件,在索引树上全部满足,筛选完成之后得到的最终结果集进行回表操作。简单来说就是减少回表操作
30. 索引失效?
1、用到了mysql内部的函数
2、模糊匹配like,以%、_开头会使索引失效
3、不等于(!=、<>)索引失效
4、is not null 、is null 可能失效(优化器决定)
5、复合索引没有最左匹配
31. 为什么模糊匹配like以%开头索引失效
失效,但是也没完全失效,当出现覆盖索引时,会遍历索引树,再进行回表查询,type=index,反之,覆盖索引没生效就会type=all
32. 能否看到一个索引执行逻辑?
可以,使用optimize_trace
打开参数:SET SESSION OPTIMIZER_TRACE="enabled=on",END_MARKERS_IN_JSON=on;
执行SQL:SELECT * FROM STU WHERE ID=99;
查看输出的逻辑json:SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
会话级关闭窗口或者手动set off都行。
主要分析输出的逻辑json,来判断怎么优化sql。
33. 单表中多个索引的优先级?
主键(唯一索引)>全值匹配(单值匹配)>最左前缀匹配>范围匹配>索引扫描>全表
34. Order by排序时能用索引吗?
可以使用,有条件就会用上索引,没有条件就不走索引
35. 索引排序内部流程是什么?
1、首先通过检索表中索引字段数据,没有索引的数据会被过滤掉
2、判断索引条件是否覆盖了select查询字段
如果覆盖了直接在内存中排序,然后输出。这个内存缓冲区大小由sort_buffer控制
如果没有覆盖,就会计算你所查询的字段是否超过数据长度限制(max_length_for_sort_data),超过了会启用双路排序,否则单路
36. 什么是双路跟单路排序?
双路:取出排序字段进行排序,排序完之后再次回表查询所需要的其他字段
单路:一次性取出所有的字段进行排序,内存不够的时候会使用到磁盘,内存与磁盘交互
37. Group by和order by 排序上的区别?
二者是差不多的,但是前者会先排序再分组,按照索引最左前缀匹配法则,其次group by 不加条件也是用上索引的,order by 必须带上过滤条件才走索引
表中有字段为null,又经常查询,那该不该建立索引?
肯定要建立索引的,is not null 可能会索引失效,is null是走索引的。当数据中有很多null的时候,is not null的情况下查询优化器也会走索引,type=range,如果null不是很多,那可能不走索引
38. Mysql内部支持缓存查询吗?
5.7支持,8.0废弃掉
39. MySQL8.0为什么废弃掉内部缓存?替代方案是什么?
缓存在于快速查询提升系统性能,但是也有一定局限性。如:频繁更新的表mysql基本上没有手段灵活管理的、sql没有要完全一致才能导致cache命中、缓存在分库分表的环境下是不起作用的、执行mysql的函数,触发器等也是失效的,当表结构或者数据发生变化,对于该表的cache也会立即全部失效。
替代方案:换数据库吧,用Redis,MongoDB等
40. MySQL内部有哪些核心模块?作用是啥?
第一大部分:连接——处理连接,鉴权,检查是否复用线程等
第二大部分:解析与优化——语法解释、优化器优化SQL
第三大部分:存储引擎——优化器优化完的SQL在存储引擎执行,读到磁盘上的数据
41. 应用层发送一条SQL,MySQL执行查询语句的内部执行过程是怎么样?
客户端通过通行协议与MySQL服务器建立连接(鉴权),然后通过SQL接口发送SQL语句,5.7版本有缓存,会先查询缓存,缓存有的就直接返回,8.0没有缓存,会进入解析阶段,解析器会校验SQL语法正确性,再拆分成树形结构(解析树),预处理器会检查解析树的SQL对应的字段,列,条件是否存在,检查完了之后会生成一个新的解析树, 查询优化器会将新的解析树转化成执行计划,查询执行引擎会按照生成的执行计划调用存储引擎提供的api接口执行SQL,随后返回给客户端
42. 一条SQL执行报“不存在此列”,这是执行到哪个节点报出的?
是在parse:解析器分析SQL语法的时候检查列
43. 一个表有多个索引,哪个阶段进行索引选择?
优化器阶段
44. MySQL支持哪些存储引擎,默认是哪个?
45. MySQL8.0自带哪些存储引擎,分别是做什么的?
Innodb:默认事务型引擎,可以确保事务提交或回滚,无特殊情况优先考虑该引擎
Myisam:对比innodb,不支持事务和行锁,缺陷:崩溃后无法安全恢复。优点:访问速度快,适用于对事务完整性没有要求为主的应用
Archive:只支持查询与插入,适用于日志、数据采集类应用
Blackhole:黑洞引擎,没有任务存储机制,所有插入的数据都会被舍弃掉,不会做数据库保存,适用于级联复制,只写binlog,不存数据,提高性能。
CSV:普通CSV文件作为MySQL的表来处理,不支持所有,但是比较方便(操作系统,文本编辑都能打开)
Memory:无视重启造成的数据丢失影响,只求快速访问。
Federated:跨库关联查询,但是这个灵活性不成熟,默认不用该引擎
46. MySQL存储引擎架构了解过吗?
47. 大厂都有自研的存储引擎,这个怎么自己开发一套呢?
参考官方:https://dev.mysql.com/doc/dev/mysql-server/latest/
48. 细说一下myisam和innodb的区别?
对比 | Myisam | Innodb |
外键 | 不支持 | 支持 |
事务 | 不支持 | 支持 |
行表锁 | 表锁,操作一条数据会锁表 | 行锁,操作一条数据不影响其他 |
缓存 | 只缓存索引,不缓存真实数据 | 缓存索引跟真实数据,所以内存大小对性能影响很直接 |
关注点 | 并发查询,节省资源,消耗少,简单业务 | 并发,事务,多表关系,更大资源 |
默认安装 | Y | Y |
默认使用 | N | Y |
自带系统表使用 | Y | N |
49. 什么是事务?特性是什么?
数据库的最小工作单元,是一个逻辑执行的整体,是不可再分割的操作集合,要么都执行,要么都不执行
50. 什么是ACID?
原子性(过程):数据库工作单元,要么都做,要么都不做
一致性(结果):从一个状态转变到另一个状态,要么成功,要么失败
隔离性:并发执行的各个事务之间不能互相干扰,也就是一个事务的执行,不能其他事务干扰
持久性:事务一旦提交,对数据库中的数据改变就应该是永久性的
51. 什么是脏读、丢失修改、不可重复读、幻读?
脏读:事务处理过程中读到了未提交的数据
修改丢失:第一个事务更新数据时,第二个事务也做了更新,未提交的情况下,第二个事务会覆盖第一个事务,第一个事务修改的结果就会被丢失
不可重复读:一个事务多次读取同一数据,在该事务没有结束的情况下,另一个事务修改了该数据,造成第一个事务读取的数据不一致
幻读:只同一个事务内,多次查询的返回结果集不一样(增加或者减少了n行记录)
52. 不可重复读和幻读的区别?
不可重复读指的是一条数据的修改,幻读指的是结果集的修改
53. MySQL是如何避免事务并发产生的问题呢?
MySQL内部是通过加锁的方式实现的,也就是配置事务隔离级别
什么是事务隔离级别?
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(read-uncommitted) | Y | Y | Y |
不可重复读(read-committed) | N | Y | Y |
可重复读(repeatable-read) | N | N | Y |
串行化(serializable) | N | N | N |
54. Innodb默认的事务隔离级别是什么?
可重复读repeatable-read
55. 如何选择事务的隔离级别?
隔离级别月底,事务请求锁越少相应性能也就越高,如果没啥特殊要求,默认的隔离级别就行了,如果系统中进行高频读写并且对一致性要求严格,就需要较高的隔离级别甚至串行化。
56. 靠缓存可以提升事务隔离级别的性能吗?
提升事务级别的目的就是提供更高的数据一致性,如果前置有缓存,那么缓存只能提供高效的读,并不能保证数据及时一致性,同事还要对缓存进行管理等额外开销
57. 事务隔离级别是怎么实现的?
读写锁和MVCC
58. 什么是一致性非锁定读和锁定读?
非锁定读:使用MVCC多版本控制
锁定读:每次读操作需要获取一个共享(读)锁,每次写操作需要获取一个写锁,共享锁之间不会产生互斥,共享锁和写锁之间,以及写锁与写锁之间会产生互斥,当出现锁竞争是,需要等锁释放后,另一个操作才能拿到锁
行锁——解决的就是多个事务同事更新一行数据
间隙锁——解决多个事务同时更新多行数据
59. 什么是MVCC,说一下内部实现细节?
MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问
MVCC的实现主要依赖:隐藏字段,read view ,undo log
隐藏字段(3个):
DB_TRX_ID:事务ID
DB_ROLL_PTR:回滚指针,用来指向该行undo log,如果该行没更新,则为空
DB_ROW_ID:innodb会使用该Id来生成聚簇索引。这就是为什么没有主键,也会有聚簇索引树
Read view:一个保存事务ID的list列表,使用read view 来记录和隔离不同事务并发时当前事务哪些是对当前事务是可以见的
Undo log:主要用来回滚数据,还可以读取可见版本的数据,以此实现非锁定读
60. MySQL的事务一致性,原子性,持久性是怎么实现的?
一致性,原子性:首先通过锁和mvcc实现一致性和原子性,其次是通过redo log实现,redo log会把事务的执行过程中对数据库所做的所有修改都记录下来,假如系统宕机重启,就可以通过redo log进行恢复
持久性:使用redo log保证事务的持久性,当事务commit时,必须先将事务的所有日志写入日志文件进行持久化(write ahead log 机制),如果断电可以从redo log恢复,如果写入失败就会直接回滚
61. 跟MySQL锁有关的
行锁:除串行化时,innodb使用的都是行锁,顾名思义,就是锁定一行数据,其他数据不受影响,所以并发能力强
表锁:串行化时,整表加锁,事务访问时申请锁,分为读锁和写锁,会导致并发下降,一般只做DDL处理时使用到
行锁实现:行锁实现是有MVCC完成的
排它锁(写锁,独占锁):排他锁也称X锁,在写操作之前要申请并获得,其他事务不能再获得任何锁
共享锁(读锁):共享锁,也称为S锁,其他事务可以继续加共享锁,但不能加排他锁
意向锁:意向锁分为共享锁(IS)和排它锁(IX),意向锁属于表锁,它与innodb的行锁不冲突,任意的两个意向锁也不会产生冲突,但是会与表锁(S和X)产生冲突
62. Innodb支持哪几种锁?
表锁,行锁,间隙锁,next-key锁等,在串行化中读加共享锁,写加排他锁,滴血互斥
63. 当前读和快照读分别是什么?
当前读:在锁定读(使用锁隔离事物) 的时候读到的是最新版本的数据
快照读:可重复读(repeatable-read) 下 mvc生效读取的是数据的快照,并不是最新版本的数据(末提交事物的数据)
64. 什么是xa协议?
65. Select for update 会产生哪些操作?
查询的时候加锁,防止被其他的写入干预,SELECT本身是一个查询语句,正常情况下,是没有锁的,而select fro update 会让select 产生一个排它锁,这个锁跟update效果一样,使两个事务无法同时更新一条记录
Select fro update 只适用于innodb,并且必须在事务中才能执行生效,进行事务操作时,对查询的结果集添加排它锁(行锁、表锁),默认是行锁,明确指定主键或者唯一索引时,是行锁,否则是表锁
66. MySQL死锁
当多个事务同时持有和请求同一资源上的锁产生循环依赖的时候就生成了死锁,A等B,B等C,C等A
解决排查方法:show processlist 查看运行的任务,unlocks tables 解锁,information_shcema.innodb_trx 查看当前运行的事务,information_shcema.innodb_locks 出现的锁,观察错误日志
优化建议:不影响需求的情况下将大事务拆分为小事务;及时提交或者回滚掉;表中的索引建立尽可能恰当;排列好不同事务之间的执行顺序。
67. MySQL中会产生哪些日志?
Error.log:mysql 启动,关闭,运行的的错误日志,当出现宕机,或者数据库服务起不来就需要分析该日志
Slow query log :慢查询日志,系统默认不开启该功能,阈值由long_query_time参数控制,默认10秒,当SQL执行超过10秒就会被记录到这个日志中
General log :客户端连接信息以及执行的SQL语句信息
Binlog:数据库操作记录日志,只记录增删改操作,不记录查找操作,该日志最大的用处就是主从复制和数据库误删恢复
Redo log:恢复更新由于宕机等原因,之前在内存中而没有刷入磁盘中的那部分数据
Undo log :回滚日志;提供多版本并发控制下的读取(MVCC)
68. Binlog刷盘机制
Binlog刷盘机制由sync_binlog参数控制
Sync_binlog:0 表示事务提交不会立马写入磁盘,而是先写page cache,对于磁盘来时,效率会快很多,但是会有丢日志的风险
Sync_binlog:1 表示每次提交都会fsync写入到磁盘
Sync_bing:>1 表示每次提交事务会先写page cache,累积了>1个事务才会fsync写入到磁盘,同样有丢日志的风险。
为1的时候强一致性,没有丢日志的问题,但是具体业务具体对待
69. Undo和Redo刷盘机制
当开启一个事务的时候,首先查询数据库中需要更新的字段,加载到内存中,形成数据脏页,此时记录undo和redo到内存缓冲区,(innodb_flush_log_at_trx_commit,0为每秒提交事务,1为事务提交立即刷盘,2每次事务提交,都写给操作系统,由操作系统接管什么时候写入磁盘),在缓冲区此时是可刷盘的,随后修改内存中的脏页数据,提交事务触发redolog 刷盘,uodo log和脏页刷盘,最后事务提交成功
70. MySQL的binlong有几种录入格式,分别有啥区别?
格式 | Row | Statement | Mixed |
说明 | 记录操作的每一行数据 | 记录操作的SQL语句 | 混合模式 |
优点 | 数据一致性高,可以flashback(闪回) | 容易理解 | 两种格式结合体 |
缺点 |
| 不支持不确定的SQL语句 | BUG多(直接放弃) |
使用情况 | 推荐 | 不推荐 | 不推荐 |
示例 | Update 100条数据,用了row格式的话,会将每条更新的数据都写一条binlog日志,所以可以看到每条数据的执行过程,从库回放也是如此,日志记录的每一条都能拿到 | 傻瓜式的执行SQL,容易引起主从数据不一致,比如主库执行一条包括uuid的SQL,当从库拿到该SQL执行的时候,此时该SQL返回的是从库的uuid,之前是主库的uuid,现在是从库的uuid,导致主从数据不一致 |
71. MySQL集群同步时为什么用binlog?优缺点是什么?
优点:Binlog是MySQL提供的日志,所有存储引擎都可用,也支撑增量同步,binlog还可以供其他中间件(HDFS,ES)读取
缺点:不支持某阶段回放,如果复制过程中一旦中断复制,就很难确定复制的offset
72. 文件如何存储emoji?
可以用BLOB用来存储二进制大对象的字段类型
73. 如何存储ip地址?
1、 使用字符串
2、 使用无符号整型
74. 如何存储长文本?
使用Text存储
75. Char与Varchar的区别跟如何选择?
前者:存储空间固定大小(最大255),没有碎片,数据存储读取都很快,缺点就是空间冗余对于非固定长度属性用char类型,造成空间浪费
后者:存储空间根据存储内容变化而变化,空间长度为L+size,优点是节约空间,缺点就是读取跟存储时需要读取信息计算下表,才能获取完整内容
用法:固定(已知范围)用char,弹性长度用varchar
76. 预编译是什么?预编译SQL有什么好处?
预编译缓存SQL结果,提高复用性并且执行效率高很多,其次提高安全性,防止SQL注入,
77. 子查与join哪个效率高?
Join效率高,虽然子查询很灵活,但是执行效率并不高,因为在执行子查的时候,会创建临时表,查完又要删除,join则没有创建删除操作,所以执行效率会比子查快一点
78. Join查询可以无限叠加吗?MySQL对join查询有什么限制不?
建议join不超过3张表做关联查询,join并不是无线叠加的,系统最多限制61张表
79. MySQL调优
1、 sql调优
2、 表结构设计调优
3、 索引调优
4、 慢查询调优
5、 操作系统调优
6、 数据库参数调优
80. Explain是什么?关键字中有哪些重要的指标?
Explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的,。
关键指标——
type:查询方式
possible_keys可能用到的索引
key:最终使用到的索引
rows:返回行数(受影响的行数)
filtered:有效率的百分比
81. count(*)、count(1)和count(列名)
count(*)、count(1):统计所有,包括null的行
count(列明):统计所有但排除null
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~学完笔记,真累~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~