MySQL常见面试题汇总(建议收藏!!!)

一、索引相关

(1)什么是索引?

索引是一种数据结构,可以帮助我们快速的进行数据的查找。

(2)索引是个什么样的数据结构呢?

索引的数据结构和具体存储引擎的实现有关,在 MySQL 中使用较多的索引有 Hash 索引,B+ 树索引等,而我们经常使用的 InnoDB 存储引擎的默认索引实现为:B+ 树索引。

(3)为什么使用索引?

(4)Innodb为什么要用自增id作为主键?

如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置, 频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE(optimize table)来重建表并优化填充页面。

(5)Hash 索引和 B+ 树索引有什么区别或者说优劣呢?

首先要知道 Hash 索引和 B+ 树索引的底层实现原理:

hash 索引底层就是 hash 表,进行查找时,调用一次 hash 函数就可以获取到相应的键值,之后进行回表查询获得实际数据。B+ 树底层实现是多路平衡查找树。对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据。

那么可以看出他们有以下的不同:

因此,在大多数情况下,直接选择 B+ 树索引可以获得稳定且较好的查询速度。而不需要使用 hash 索引。

(6)什么是聚簇索引

聚簇索引就是按照每张表的 主键 构造一棵B+树,同时叶子节点中存放的就是整张表的行记录数据。

在 InnoDB 中,只有主键索引是聚簇索引,如果没有主键,则挑选一个唯一键建立聚簇索引。如果没有唯一键,则MySQL自动为InnoDB表生成一个隐含字段来建立聚簇索引,这个字段长度为6个字节,类型为长整形。

当查询使用聚簇索引时,在对应的叶子节点,可以获取到整行数据,因此不用再次进行回表查询。

(7)说一说索引的底层实现?

Hash索引

基于哈希表实现,只有精确匹配索引所有列的查询才有效,对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),并且Hash索引将所有的哈希码存储在索引中,同时在索引表中保存指向每个数据行的指针。

MySQL常见面试题汇总(建议收藏!!!)

B-Tree索引(MySQL使用B+Tree)

B-Tree能加快数据的访问速度,因为存储引擎不再需要进行全表扫描来获取数据,数据分布在各个节点之中。

MySQL常见面试题汇总(建议收藏!!!)

B+Tree索引

是B-Tree的改进版本,同时也是数据库索引所采用的存储结构。数据都在叶子节点上,并且增加了顺序访问指针,每个叶子节点都指向相邻的叶子节点的地址。相比B-Tree来说,进行范围查找时只需要查找两个节点,进行遍历即可。而B-Tree需要获取所有节点,相比之下B+Tree效率更高。

B+tree性质:

MySQL常见面试题汇总(建议收藏!!!)

(8)索引有哪些优缺点?

索引的优点

索引的缺点

(9)聚簇索引和非聚簇索引的区别

(10)MyISAM和InnoDB实现B+树索引方式的区别是什么?

在根据主键索引搜索时,直接找到key所在的节点即可取出数据;根据辅助索引查找时,则需要先取出主键的值,再走一遍主索引。 因此,在设计表的时候,不建议使用过长的字段为主键,也不建议使用非单调的字段作为主键,这样会造成主索引频繁分裂。

总结:InnoDB 主键索引使用的是聚簇索引,MyISAM 不管是主键索引,还是二级索引使用的都是非聚簇索引。

(11)MySQL中有几种索引类型,可以简单说说吗?

(12)覆盖索引是什么?

如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称 之为“覆盖索引”。

我们知道在InnoDB存储引 擎中,如果不是主键索引,叶子节点存储的是主键值。最终还是要“回表”,也就是要通过主键再查找一次,这样就 会比较慢。覆盖索引就是把要查询出的列和索引是对应的,不做回表操作!

(13)非聚簇索引一定会回表查询吗?

不一定,这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再进行回表查询。

举个简单的例子,假设我们在员工表的年龄上建立了索引,那么当进行select age from employee where age < 20的查询时,在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询。

(14)联合索引是什么?为什么需要注意联合索引中的顺序?

MySQL 可以使用多个字段同时建立一个索引,叫做联合索引。在联合索引中,如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引。

具体原因为:

MySQL 使用索引时需要索引有序,假设现在建立了"name,age,school"的联合索引,那么索引的排序为:先按照name排序,如果 name 相同,则按照 age 排序,如果 age 的值也相等,则按照 school 进行排序。

当进行查询时,此时索引仅仅按照 name 严格有序,因此必须首先使用 name 字段进行等值查询,之后对于匹配到的列而言,其按照 age 字段严格有序,此时可以使用 age 字段用做索引查找,以此类推。因此在建立联合索引的时候应该注意索引列的顺序,一般情况下,将查询需求频繁或者字段选择性高的列放在前面。此外可以根据特例的查询或者表结构进行单独的调整。

(15)创建的索引有没有被使用到?或者说怎么才可以知道这条语句运行很慢的原因?

MySQL 提供了 explain 命令来查看语句的执行计划,MySQL 在执行某个语句之前,会将该语句过一遍查询优化器,之后会拿到对语句的分析,也就是执行计划,其中包含了许多信息。可以通过其中和索引有关的信息来分析是否命中了索引,例如possilbe_key,key,key_len等字段,分别说明了此语句可能会使用的索引,实际使用的索引以及使用的索引长度。

“执行计划”中需要知道的几个“关键字”

(16)那么在哪些情况下会发生针对该列创建了索引但是在查询的时候并没有使用呢?

以上情况,MySQL无法使用索引。

(17)为什么Mysql用B+树做索引而不用B-树或红黑树、二叉树

主要原因:B+树只要遍历叶子节点就可以实现整棵树的遍历,而且在数据库中基于范围的查询是非常频繁的,而B树只能中序遍历所有节点,效率太低。

B-tree:

Hash:

二叉树: 树的高度不均匀,不能自平衡,查找效率跟数据有关(树的高度),并且IO代价高。

红黑树: 树的高度随着数据量增加而增加,IO代价高。

(18)MySQL索引种类

普通索引、唯一索引(主键索引、唯一索引)、联合索引、全文索引、空间索引

(19)索引在什么情况下遵循最左前缀的规则?

在建立了联合索引的前提条件下,数据库会一直从左向右的顺序依次查找,直到遇到了范围查询(>,<,between,like等)

二、事务相关

(1)什么是事务?

事务是一系列的数据库操作,他们要符合 ACID 特性,事务是数据库应用的基本单位。MySQL 事务主要用于处理操作量大,复杂度高的数据。

(2)ACID是什么?可以详细说一下吗?

(3)MySQL中为什么要有事务回滚机制?

而在 MySQL 中,恢复机制是通过回滚日志(undo log)实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后在对数据库中的对应行进行写入。当事务已经被提交之后,就无法再次回滚了。

回滚日志作用:

  1. 能够在发生错误或者用户执行 ROLLBACK 时提供回滚相关的信息
  2. 在整个系统发生崩溃、数据库进程直接被杀死后,当用户再次启动数据库进程时,还能够立刻通过查询回滚日志将之前未完成的事务进行回滚,这也就需要回滚日志必须先于数据持久化到磁盘上,是我们需要先写日志后写数据库的主要原因。

(4)数据库并发事务会带来哪些问题?

数据库并发事务会带来 脏读、幻读、丢弃更改、不可重复读 这四个常见问题,其中:

当设置A事务只能读取 B 事务已经提交的部分,会造成在 A 事务内的两次查询,结果竟然不一样,因为在此期间 B 事务进行了提交操作。

脏读图解:

MySQL常见面试题汇总(建议收藏!!!)

第一个事务首先读取var变量为50,接着准备更新为100的时,并未提交,第二个事务已经读取var为100,此时第一个事务做了回滚。最终第二个事务读取的var和数据库的var不一样。

幻读图解:

MySQL常见面试题汇总(建议收藏!!!)

T1 读取某个范围的数据,T2 在这个范围内插入新的数据,T1 再次读取这个范围的数据,此时读取的结果和和第一次读取的结果不同。

丢弃修改图解:

MySQL常见面试题汇总(建议收藏!!!)

T1 和 T2 两个事务都对一个数据进行修改,T1 先修改,T2 随后修改,T2 的修改覆盖了 T1 的修改。例如:事务1读取某表中的数据A=50,事务2也读取A=50,事务1修改A=A+50,事务2也修改A=A+50,最终结果A=100,事务1的修改被丢失。

不可重复读图解:

MySQL常见面试题汇总(建议收藏!!!)

T2 读取一个数据,T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。

(5)怎么解决这些问题呢?MySQL 的事务隔离级别了解吗?

MySQL 的四种隔离级别如下:

MySQL常见面试题汇总(建议收藏!!!)

(6)Innodb使用的是哪种隔离级别呢?

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重复读)

原因: 与 SQL 标准不同的地方在于InnoDB 存储引擎在 REPEATABLE-READ(可重读)事务隔离级别 下使用的是 Next-Key Lock 锁算法 ,因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server)是不同的。所以 说InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读) 已经可以完全保证事务的隔离性要 求,即达到了 SQL标准的SERIALIZABLE(可串行化)隔离级别。

InnoDB 存储引擎在分布式事务 的情况下一般会用到SERIALIZABLE(可串行化)隔离级别。

(7)不可重复读和幻读区别是什么?可以举个例子吗?

不可重复读的重点是修改,幻读的重点在于新增或者删除。

三、锁相关

(1)对 MySQL 的锁了解吗?

当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制.

就像酒店的房间,如果大家随意进出,就会出现多人抢夺同一个房间的情况,而在房间上装上锁,申请到钥匙的人才可以入住并且将房间锁起来,其他人只有等他使用完毕才可以再次使用.

(2)MySQL 锁的分类

Mysql中锁的分类按照不同类型的划分可以分成不同的锁:

按照 锁的粒度 划分可以分成:

按照 使用的方式 划分可以分为:

按照 思想 的划分:

(3)行级锁、表级锁、页级锁的描述与特点

行级锁:

表级锁:

页级锁:

(4)共享锁 、 排他锁的描述

共享锁:

描述:

用法:

排他锁:

描述:

用法:

用上面的例子来说就是用户的行为有两种,一种是来看房,多个用户一起看房是可以接受的. 一种是真正的入住一晚,在这期间,无论是想入住的还是想看房的都不可以.

(5)悲观锁与乐观锁

乐观锁, 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。

悲观锁,顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

(6)数据库悲观锁和乐观锁的原理和应用场景分别有什么?

悲观锁,先获取锁,再进行业务操作,一般就是利用类似 SELECT … FOR UPDATE 这样的语句,对数据加锁,避免其他事务意外修改数据。当数据库执行SELECT … FOR UPDATE时会获取被select中的数据行的行锁,select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。

乐观锁,先进行业务操作,只在最后实际更新数据时进行检查数据是否被更新过。Java 并发包中的 AtomicFieldUpdater 类似,也是利用 CAS 机制,并不会对数据加锁,而是通过对比数据的时间戳或者版本号,来实现乐观锁需要的版本判断。

(7)MySQL常用存储引擎的锁机制?

(8)InnoDB 存储引擎有几种锁算法?

(9)什么是死锁?

是指二个或者二个以上的进程在执行时候,因为争夺资源造成相互等待的现象,进程一直处于等待中,无法得到释放,这种状态就叫做死锁。

(10)死锁出现的案列?

批量入库,存在则更新,不存在则插入,insert into tab(xx,xx) on duplicate key update xx=‘xx’。

(11)如何处理死锁?

  1. 通过innodblockwait_timeout来设置超时时间,一直等待直到超时
  2. 发起死锁检测,发现死锁之后,主动回滚死锁中的事务,不需要其他事务继续

(12)如何避免死锁?

  1. 为了在单个innodb表上执行多个并发写入操作时避免死锁,可以在事务开始时,通过为预期要修改行,使用select …for update语句来获取必要的锁,即使这些行的更改语句是在之后才执行的
  2. 在事务中,如果要更新记录,应该直接申请足够级别的锁,即排他锁,而不应先申请共享锁,更新时在申请排他锁。因为这时候当用户在申请排他锁时,其他事务可能又已经获得了相同记录的共享锁
  3. 如果事务需要修改或锁定多个表,则应在每个事务中以相同的顺序使用加锁语句。在应用中,如果不同的程序会并发获取多个表,应尽量约定以相同的顺序来访问表,这样可以大大降低产生死锁的机会
  4. 通过 select …lock in share mode获取行的读锁后,如果当前事务在需要对该记录进行更新操作,则很有可能造成死锁
  5. 改变事务隔离级别

(13)Innodb默认是如何对待死锁的?

innodb默认是使用设置死锁时间来让死锁超时的策略,默认innodblockwait_timeout设置的时长是50s

(14)如何开启死锁检测?

设置innodbdeadlockdetect设置为on可以主动检测死锁,在innodb中这个值默认就是on开启的状态

(15)什么是全局锁?它的应用场景有哪些?

全局锁就是对整个数据库实例加锁,它的典型使用场景就是做全库逻辑备份,这个命令可以使用整个库处于只读状态,使用该命令之后,数据更新语句,数据定义语句,更新类事务的提交语句等操作都会被阻塞。

(16)使用全局锁会导致的问题?

(17)优化锁方面你有什么建议?

四、存储引擎相关

(1)MySQL 支持哪些存储引擎?

MySQL 支持多种存储引擎,比如InnoDB,MyISAM,Memory,Archive等等。在大多数的情况下,直接选择使用 InnoDB 引擎都是最合适的,InnoDB 也是 MySQL 的默认存储引擎。

(2)InnoDB 和 MyISAM 有什么区别?

InnoDB

MyISAM

总结:

(3)你了解MySQL的内部构造吗?一般可以分为哪两个部分?

可以分为服务层和存储引擎层两部分,其中:

服务层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。

存储引擎层负责数据的存储和提取。 其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。现在最常用的存储引擎是InnoDB,它从MySQL5.5.5版本开始成为了默认的存储引擎。

MySQL常见面试题汇总(建议收藏!!!)

(4)说一下MySQL是如何执行一条SQL的?具体步骤有哪些?

Server层按顺序执行sql的步骤为:

1.客户端请求->

2.连接器(验证用户身份,给予权限) ->

3.查询缓存(存在缓存则直接返回,不存在则执行后续操作)->

4.分析器(对SQL进行词法分析和语法分析操作) ->

5.优化器(主要对执行的sql优化选择最优的执行方案方法) ->

6.执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口)->

7.去引擎层获取数据返回(如果开启查询缓存则会缓存查询结果)

简单概括:

(5)SQL 的执行顺序?

SELECT DISTINCT

< select_list >

FROM

< left_table > < join_type >

JOIN < right_table > ON < join_condition >

WHERE

< where_condition >

GROUP BY

< group_by_list >

HAVING

< having_condition >

ORDER BY

< order_by_condition >

LIMIT < limit_number >

它的执行顺序你知道吗?这道题就给你一个回答。

FROM 连接

首先,对 SELECT 语句执行查询时,对FROM 关键字两边的表执行连接,会形成笛卡尔积,这时候会产生一个虚表VT1(virtual table)

ON 过滤

然后对 FROM 连接的结果进行 ON 筛选,创建 VT2,把符合记录的条件存在 VT2 中。

JOIN 连接

第三步,如果是 OUTER JOIN(left join、right join) ,那么这一步就将添加外部行,如果是 left join 就把 ON 过滤条件的左表添加进来,如果是 right join ,就把右表添加进来,从而生成新的虚拟表 VT3。

WHERE 过滤

第四步,是执行 WHERE 过滤器,对上一步生产的虚拟表引用 WHERE 筛选,生成虚拟表 VT4。

GROUP BY

根据 group by 字句中的列,会对 VT4 中的记录进行分组操作,产生虚拟机表 VT5。果应用了group by,那么后面的所有步骤都只能得到的 VT5 的列或者是聚合函数(count、sum、avg等)。

HAVING

紧跟着 GROUP BY 字句后面的是 HAVING,使用 HAVING 过滤,会把符合条件的放在 VT6

SELECT

第七步才会执行 SELECT 语句,将 VT6 中的结果按照 SELECT 进行刷选,生成 VT7

DISTINCT

在第八步中,会对 TV7 生成的记录进行去重操作,生成 VT8。事实上如果应用了 group by 子句那么 distinct 是多余的,原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的。

ORDER BY

应用 order by 子句。按照 order_by_condition 排序 VT8,此时返回的一个游标,而不是虚拟表。sql 是基于集合的理论的,集合不会预先对他的行排序,它只是成员的逻辑集合,成员的顺序是无关紧要的。

SQL 语句执行的过程如下:

MySQL常见面试题汇总(建议收藏!!!)

(6)简述触发器、函数、视图、存储过程?

(7)听说过视图吗?那游标呢?

(8)视图的作用是什么?可以更改吗?

视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询;不包含任何列或数据。使用视图可以简化复杂的 sql 操作,隐藏具体的细节,保护数据;视图创建后,可以使用与表相同的方式利用它们。

视图不能被索引,也不能有关联的触发器或默认值,如果视图本身内有order by 则对视图再次order by将被覆盖。

创建视图:

create view xxx as xxxx

对于某些视图比如未使用联结子查询分组聚集函数Distinct Union等,是可以对其更新的,对视图的更新将对基表进行更新;但是视图主要用于简化检索,保护数据,并不用于更新,而且大部分视图都不可以更新。

五、表结构相关

(1)为什么要尽量设定一个主键?

主键是数据库确保数据行在整张表唯一性的保障,即使业务上本张表没有主键,也建议添加一个自增长的 ID 列作为主键.设定了主键之后,在后续的删改查的时候可能更加快速以及确保操作数据范围安全。

(2)主键使用自增 ID 还是 UUID?

推荐使用自增ID,不要使用 UUID。

因为在 InnoDB存储引擎中,主键索引是作为聚簇索引存在的,也就是说,主键索引的B+树叶子节点上存储了主键索引以及全部的数据(按照顺序),如果主键索引是自增ID,那么只需要不断向后排列即可,如果是UUID,由于到来的ID与原来的大小不确定,会造成非常多的数据插入,数据移动,然后导致产生很多的内存碎片,进而造成插入性能的下降.

总之,在数据量大一些的情况下,用自增主键性能会好一些。

图片来源于《高性能MySQL》: 其中默认后缀为使用自增ID,_uuid为使用 UUID为主键的测试,测试了插入 100w 行和 300w 行的性能。

MySQL常见面试题汇总(建议收藏!!!)

(3)字段为什么要求定义为not null?

null 值会占用更多的字节,且会在程序中造成很多与预期不符的情况。

(4)如果要存储用户的密码散列,应该使用什么字段进行存储?

密码散列,用户身份证号等固定长度的字符串应该使用 char 而不是 varchar 来存储,这样可以节省空间且提高检索效率。

(5)说一说Drop、Delete与Truncate的共同点和区别?

(6)数据库中的主键、超键、候选键、外键是什么?

六、其他问题

(1)MySQL 中的 varchar 和 char 有什么区别?

char 是一个定长字段,假如申请了char(10)的空间,那么无论实际存储多少内容。该字段都占用 10 个字符,而 varchar 是变长的,也就是说申请的只是最大长度,占用的空间为实际字符长度 +1,最后一个字符存储使用了多长的空间

在检索效率上来讲,char > varchar,因此在使用中,如果确定某个字段的值的长度,可以使用 char,否则应该尽量使用 varchar。例如存储用户 MD5 加密后的密码,则应该使用 char。

(2)varchar(10) 和 int(10) 代表什么含义?

varchar的10代表了申请的空间长度,也是可以存储的数据的最大长度,而int的10只是代表了展示的长度,不足10位以0填充.也就是说,varchar(10) 和int(10)所能存储的数字大小以及占用的空间都是相同的,只是在展示时按照长度展示.

(3)MySQL的binlog有有几种录入格式?分别有什么区别?

有三种格式:statement、row和mixed.

(4)超大分页怎么处理?

超大的分页一般从两个方向上来解决.:

(5)说一说三个范式?

在设计数据库结构的时候,要尽量遵守三范式,如果不遵守,必须有足够的理由。比如性能,事实上我们经常会为了性能而妥协数据库的设计。

(6)left join、right join以及inner join的区别?

(7)什么是数据库约束,常见的约束有哪几种?

数据库约束用于保证数据库、表数据的完整性(正确性和一致性)。

可以通过定义约束索引触发器来保证数据的完整性。总体来讲,约束可以分为:

(8)什么是sql注入?

SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。

(9)简述数据库的读写分离?

读写分离为了确保数据库产品的稳数据定性,很多数据库拥有双机热备功能。也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器;第二台数据库服务器,主要进行读的操作。

(10)MySQL数据库cpu飙升的话,要怎么处理呢?

排查过程:

处理:

(11)MYSQL的主从延迟,你怎么解决?

主从复制分了五个步骤进行:

MySQL常见面试题汇总(建议收藏!!!)

主从同步延迟的原因:

一个服务器开放N个链接给客户端来连接的,这样有会有大并发的更新操作, 但是从服务器的里面读取binlog的线程仅有一个,当某个SQL在从服务器上执行的时间稍长 或者由于某个SQL要进行锁表就会导致,主服务器的SQL大量积压,未被同步到从服务器里。这就导致了主从不一致, 也就是主从延迟。

主从同步延迟的解决办法:

(12)如果让你做分库与分表的设计,简单说说你会怎么做?

分库分表方案:

常用的分库分表中间件:

分库分表可能遇到的问题:

(13)count(1)、count(*)与count(列名)的执行区别

执行效果上 :

执行效率上:

(14)sql 语句中where 1=1的作用

1=1的坏处

(15)sql中null与空值的区别

七、优化相关

(1)日常工作中你是怎么优化SQL的?

(1.1)表结构优化

1.尽量使用数字型字段

若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

2.尽可能的使用 varchar 代替 char

变长字段存储空间小,可以节省存储空间。

3.当索引列大量重复数据时,可以把索引删除掉

比如有一列是性别,几乎只有男、女、未知,这样的索引是无效的。

(1.2)查询优化

  1. 应尽量避免在 where 子句中使用!=或<>操作符
  2. 应尽量避免在 where 子句中使用 or 来连接条件
  3. 任何查询也不要出现select *
  4. 避免在 where 子句中对字段进行 null 值判断

(1.3)索引优化

  1. 对作为查询条件和 order by的字段建立索引
  2. 避免建立过多的索引,多使用组合索引

(1.4)慢查询优化

  1. 分析语句,是否加载了不必要的字段/数据
  2. 分析 SQL 执行句话,是否命中索引等
  3. 如果 SQL 很复杂,优化 SQL 结构
  4. 如果表数据量太大,考虑分表
展开阅读全文

页面更新:2024-05-01

标签:节点   字段   视图   语句   函数   索引   效率   常见   操作   建议   数据库   收藏   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top