MySQL进阶-开发篇(hot🔥)

小龙coding大约 49 分钟

Explain 实际开发怎样使用的?

Explain 可以用来模拟 MySQL 优化器执行 SQL 查询语句,从而知道 MySQL 怎么处理你的 SQL 语句,生成 SQL 的执行计划,凭此可以帮助分析其性能瓶颈

img

我们可以通过 使用 explian+SQL 的命令,生产对应 SQL 的执行计划

通过生成的信息,我们可以结合各个字段分析得到 索引的使用情况,查询行的访问方式(全表扫描、索引全扫描 or 唯一索引等)、读取表的顺序等。

不过,在业务中,我们平时主要看这几个字段:

type:表示MySQL在表中找到所需行的方式,或者叫访问类型

  • type=ALL,全表扫描,MySQL遍历全表来找到匹配行
  • type=index,索引全扫描
  • type=range,索引范围扫描
  • type=eq_ref,唯一索引
  • type=NULL,MySQL不用访问表或者索引,直接就能够得到结果(性能最好)

possible_keys: 表示查询可能使用的索引

key: 实际使用的索引

key_len: 使用索引字段的长度

rows: 扫描行的数量

Extra

  • using index:覆盖索引,不回表
  • using where:回表查询
  • using filesort:需要额外的排序,不能通过索引得到排序结果

Explain 实际开发怎样使用的?

  1. 使用Explain命令:在你的SQL查询语句前加上Explain关键字,然后执行。例如,如果你的查询语句是 SELECT * FROM table WHERE id = 1,你可以这样使用Explain:EXPLAIN SELECT * FROM table WHERE id = 1。
  2. 查看Explain结果:Explain命令会返回一个表格,其中包含了查询执行的详细信息。这些信息包括:
    • id:查询的标识符。
    • select_type:查询的类型。
    • table:查询的表。
    • type:连接类型,这是一个重要的指标,可以反映查询的性能。
    • possible_keys:可能应用的索引。
    • key:实际使用的索引。
    • key_len:使用的索引的长度。
    • ref:哪些列或常量被用于查找索引列。
    • rows:MySQL认为必须检查的行数。
    • Extra:关于查询的额外信息。
  3. 分析Explain结果:通过分析Explain的结果,你可以找出查询的瓶颈,然后进行优化。例如:
    • 如果type列的值是ALL,那么说明MySQL进行了全表扫描,这通常意味着你需要添加索引来优化查询。
    • 如果rows列的值非常大,那么说明MySQL需要检查的行数很多,可能需要优化你的查询条件。
  4. 优化查询:根据Explain的结果,你可以进行相应的优化,例如添加索引、修改查询条件等。然后你可以再次使用Explain命令,看看优化的效果。

可以使用MySQL直接存储文件吗?什么时候存?什么时候不存?存储的时候有遇到过什么问题吗?

关于MySQL直接存储文件的问题

  1. MySQL可以通过BLOB(Binary Large Object)类型来直接存储文件,包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB,它们分别可以存储不同大小的数据。
  2. 这种方式适合存储小型的文件,如图片、文档等;存储文件时,一般是将文件转换为二进制数据,然后存储在BLOB类型的字段
  3. 但是,直接在MySQL中存储文件也有一些问题,如果文件较大可能性能下降、存储限制、且还有备份和恢复困难问题等。

因此,我们需要根据业务需求和技术特性去选择,比如:

  1. 小型文件存储:如果需要存储的是小型文件,如用户头像、文档等,可以考虑直接存储在数据库中,如MySQL的BLOB字段。
  2. 大型文件存储:如果需要存储的是大型文件,如视频、大型图片等,可以考虑使用文件系统或云存储服务。例如,可以将文件存储在本地文件系统、网络文件系统(NFS)、分布式文件系统(如Hadoop的HDFS)中,或者使用云存储服务,如阿里云的OSS、亚马逊的S3等。
  3. 高并发读写:如果业务场景需要高并发读写,可以选择性能高、可扩展性强的存储系统,如分布式文件系统或云存储服务。
  4. 数据安全和备份:如果对数据安全和备份有较高要求,可以选择支持数据加密、访问控制和备份恢复的存储系统,如云存储服务。
  5. 成本考虑:如果需要考虑成本,可以根据数据量、访问频率等因素,选择合适的存储方案。例如,对于访问频率低但需要长期存储的数据,可以选择成本较低的冷存储服务。

以上只是一些基本的推荐,具体的选择还需要根据业务需求和技术特性进行详细分析。

如何存储Emoji 乱码怎么办?

在 MySQL 中存储 Emoji 表情,需要使用 utf8mb4 字符集,因为 Emoji 表情是四字节的 Unicode 字符,而 MySQL 的 utf8 字符集最多只支持三字节的 Unicode 字符

如何存储 IP 地址⭐?

在 MySQL 中,有两种常见的方式可以用来存储 IP 地址:

  1. 存储为字符串:可以将 IP 地址存储为 VARCHAR 类型的字符串。例如,IPv4 地址可以存储为形如 "192.168.1.1" 的字符串,IPv6地址可以存储为形如 "2001:0db8:85a3:0000:0000:8a2e:0370:7334" 的字符串。这种方式的优点是直观易懂,但是占用的存储空间较大。
  2. 存储为整数:可以将IP地址转换为整数进行存储。例如,IPv4地址可以转换为一个32位的无符号整数,IPv6地址可以转换为一个128位的整数。这种方式的优点是占用的存储空间较小,但是需要在存储和读取时进行转换。

MySQL提供了INET_ATON 和 INET_NTOA 两个函数,可以方便地在 IP 地址的字符串表示和整数表示之间进行转换。例如:

SELECT INET_ATON('192.168.1.1'); -- 将

SELECT INET_NTOA(3232235777); -- 将整数转换为IP地址

对于IPv6地址,MySQL 5.6及以上版本还提供了INET6_ATON和INET6_NTOA两个函数。

如果你的应用需要频繁地进行IP地址的比较和排序操作,存储为整数的方式可能会更加高效;如果应用主要是展示IP地址,而不需要进行复杂的操作,那么直接将IP地址存储为字符串可能会更方便。

长文本如何存储?大段文本如何设计表结构?大段文本查找时如何建立索引?有没有在开发中使用过TEXT.BLOB 数据类型?

  1. 长文本的存储:
    1. 在MySQL中,长文本通常使用TEXT或BLOB类型进行存储。
    2. TEXT用于存储非二进制的长文本,BLOB用于存储二进制的长数据。
    3. TEXT和BLOB类型都有多个不同的长度级别,例如TINYTEXT/TINYBLOB、TEXT/BLOB、MEDIUMTEXT/MEDIUMBLOB、LONGTEXT/LONGBLOB。
  2. 设计表结构
    • 如果一条记录中的长文本字段不是经常被访问,可以将长文本字段单独存储在一个表中,与主表进行关联,以提高主表的查询性能。
    • 如果长文本字段的内容有固定的结构或者需要进行复杂的处理,可以将其分解为多个字段或者存储为JSON格式。
  3. 建立索引:
    • MySQL不允许直接对TEXT或BLOB类型的字段建立完整的索引,但可以对其前N个字符建立索引。
    • 可以使用全文索引(FULLTEXT)来提高长文本字段的搜索性能。全文索引可以对文本内容进行分词,然后建立倒排索引,支持复杂的文本搜索查询。
  4. 使用TEXT/BLOB数据类型:
    • TEXT和BLOB类型通常用于存储如文章内容、用户评论、图片数据等大段的文本或者二进制数据。
    • 需要注意的是,由于TEXT和BLOB类型的数据存储在独立的区域,频繁地访问这些字段可能会影响数据库的性能。
    • 在设计数据库和编写SQL查询时,应尽量避免无必要的访问TEXT和BLOB类型的字段。

日期,时间如何存取? TIMESTAMP,DATETIME的区别是什么? 为什么不使用字符串存储日期?如果需要使用时间戳 timestamp和int该如何选择?

  1. 日期和时间的存取
    • 在MySQL中,日期和时间可以使用DATE、TIME、DATETIME、TIMESTAMP等类型进行存储。
    • 使用相应的函数,如NOW()、CURDATE()、CURTIME()等获取当前的日期和时间。
    • 使用DATE_FORMAT()函数格式化日期和时间的输出,使用STR_TO_DATE()函数将字符串转换为日期和时间。
  2. TIMESTAMP和DATETIME的区别
    • TIMESTAMP和DATETIME都可以用来存储日期和时间,但它们在存储范围、存储格式和时区处理上有所不同。
    • TIMESTAMP的存储范围是 '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC,而 DATETIM E的存储范围是 '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59'。
    • TIMESTAMP在存储时会将日期和时间转换为UTC,在检索时会将其转换回当前时区的日期和时间,而DATETIME则直接存储日期和时间,不进行时区转换。
    • TIMESTAMP占用4个字节的存储空间,而DATETIME占用8个字节。
  3. 为什么不使用字符串存储日期
    • 使用字符串存储日期会占用更多的存储空间。
    • 使用字符串存储日期会使日期和时间的计算变得复杂,例如需要使用字符串函数进行日期的加减操作。
    • 使用字符串存储日期会使日期的排序和比较变得复杂,例如需要使用字符串函数进行日期的比较和排序。
  4. 时间戳 timestamp 和 int 的选择:
    • 如果需要存储的是 UNIX 时间戳(即1970年1月1日以来的秒数),可以使用INT类型,这样可以节省存储空间。
    • 如果需要存储的是日期和时间,并且需要进行日期和时间的计算、比较和格式化,那么应该使用TIMESTAMP或DATETIME类型。
    • 如果需要处理时区,应该使用 TIMESTAMP,因为它会自动进行时区转换。如果不需要处理时区,或者需要存储的日期和时间超出了 TIMESTAMP 的范围,应该使用 DATETIME。

char与varchar的区别?如何选择?

  1. CHAR 和 VARCHAR 的区别:

    • CHAR是固定长度的字符类型,当存储的值少于定义的长度时,MySQL会在值的右侧用空格填充;在检索时,会删除这些填充的空格。CHAR最大可以存储255个字符。
    • VARCHAR是可变长度的字符类型,只存储实际需要的字符,并在值的前面使用1到2个字节来存储值的长度。VARCHAR最大可以存储65535个字符,但实际的最大长度取决于最大行大小和使用的字符集。
  2. 如何选择 CHAR VARCHAR

    • 如果列的值几乎是固定长度的,例如性别、国家代码等,那么应该使用CHAR,因为CHAR在存储和检索时的性能比VARCHAR更好。
    • 如果列的值的长度有很大的变化,例如姓名、地址等,那么应该使用VARCHAR,因为VARCHAR可以节省存储空间。
    • 如果列的值的最大长度超过了255个字符,那么必须使用VARCHAR,因为CHAR的最大长度是255个字符。
  3. 在性能方面,CHAR和VARCHAR各有优势:

    CHAR的优势:

    • CHAR类型的字段,无论实际数据长度如何,都会预留固定的存储空间,因此在读取数据时速度较快,这在需要频繁读取数据的情况下是一个优势。
    • CHAR在存储和检索时,由于其固定长度的特性,不需要额外的字节来记录数据长度,因此在处理大量数据时,CHAR 可能会有更好的性能。

    VARCHAR的优势:

    • VARCHAR 类型的字段,只占用实际数据长度的存储空间,因此在存储大量长度不一的字符串时,可以节省存储空间,这在存储空间有限的情况下是一个优势。
    • VARCHAR 在存储时,只需要额外的1到2个字节来存储数据长度,因此在处理大量数据时,如果数据长度差异较大,VARCHAR 可能会有更好的性能。

总的来说,CHAR 和 VARCHAR 的性能差异主要取决于实际数据的特性和应用场景。如果数据长度几乎固定,那么 CHAR 可能会有更好的性能。如果数据长度有很大的变化,那么 VARCHAR 可能会有更好的性能。

财务计算有没有出现过错乱?怎样解决?

在进行财务计算时,可能会出现的问题主要包括:

  1. 精度丢失:由于计算机在处理浮点数时,由于内部表示和计算的限制,可能会产生误差。
  2. 舍入错误:在进行四舍五入等操作时,可能会出现误差。

解决这些问题的方法包括:

  1. 使用定点数进行计算:在数据库中,可以使用DECIMAL或NUMERIC类型来存储和处理财务数据。这两种类型可以精确地表示小数,避免了浮点数的精度问题。
  2. 通常我们采用 BigDecimal 处理。

在进行财务计算时,还需要注意的几点包括:

  1. 避免使用浮点数进行比较:由于精度问题,两个看似相等的浮点数可能不会被判断为相等。
  2. 明确舍入的规则:在进行舍入操作时,要明确舍入的规则,避免舍入误差。
  3. 注意数值溢出的问题:在处理大量的财务数据时,要注意数值溢出的问题。

decimal与 float,double的区别是什么?

decimal,float和double都是用于表示实数的数据类型,但它们在精度和表示方式上有所不同:

  1. decimal:decimal是一种精确的小数类型,适合用于财务和货币计算。decimal类型的精度是固定的,可以在声明时指定。例如,decimal(18, 9)表示总共有18位数字,其中9位是小数部分。因此,decimal可以保留任意位数的小数,精度取决于声明时指定的位数。但存储空间和计算速度上可能会较慢。
  2. float:float是一种单精度浮点数类型,其精度大约是6-7位有效数字,小数位数取决于整数部分的大小。例如,如果整数部分有3位,那么小数部分可以保留3-4位。由于精度问题,float类型不适合用于需要精确计算的场合,但存储空间和计算速度较快。
  3. double:double是一种双精度浮点数类型,其精度大约是15-17位有效数字,小数位数同样取决于整数部分的大小。例如,如果整数部分有3位,那么小数部分可以保留12-14位。double类型的存储空间和计算速度介于float和decimal之间。

总的来说,选择哪种类型取决于具体的需求。如果需要精确的计算,应该使用decimal。如果对精度要求不高,但需要较快的计算速度,可以使用float或double。

浮点类型如何选型?为什么?

选择浮点类型主要取决于以下几个因素:

  1. 精度需求:如果你的应用需要高精度的计算,例如财务计算或者科学计算,那么你可能需要使用高精度的浮点类型,如decimal或double。decimal可以提供最高的精度,但是它的计算速度和存储空间需求都比较大。double 的精度稍低,但是它的计算速度和存储空间需求都比decimal小。
  2. 性能需求:如果你的应用需要快速的计算,那么你可能需要使用性能较好的浮点类型,如float或double。float的计算速度和存储空间需求都比double和decimal小,但是它的精度也最低。
  3. 存储空间需求:如果你的应用需要存储大量的浮点数,那么你可能需要使用存储空间需求较小的浮点类型,如float。float的存储空间需求比double和decimal小,但是它的精度也最低。

总的来说,选择浮点类型需要根据你的应用的具体需求来决定。如果你需要高精度的计算,那么你应该选择decimal或double;如果你需要快速的计算或者存储空间需求较小,那么你应该选择 float。

预编译sql是什么?预编译sql有什么好处?

预编译SQL是一种数据库查询技术,它允许数据库管理系统预先解析和优化SQL语句,然后在需要时使用这些预编译的语句。预编译SQL语句通常用于需要多次执行的查询或更新操作。

比如:创建了一个预编译的SQL语句"SELECT * FROM users WHERE username = ? AND password = ?",然后我们使用PreparedStatement 的 setString方法来设置参数。最后,我们使用executeQuery方法来执行查询。(JDBC)

预编译SQL有以下好处:

  1. 提高性能:预编译SQL可以提高数据库查询的性能。因为数据库只需要解析和优化一次SQL语句,然后就可以多次使用这个预编译的语句。这样可以避免每次执行查询时都要解析和优化SQL语句,从而提高查询的速度。
  2. 防止SQL注入:预编译SQL可以有效防止SQL注入攻击。因为预编译SQL使用参数化查询,这样就可以防止恶意用户通过修改SQL语句来执行非法操作。
  3. 提高代码的可读性和可维护性:预编译SQL使用参数化查询,这样可以使SQL语句更易于理解和维护。因为参数化查询将SQL语句和参数分开,这样就可以使SQL语句更清晰,也更容易修改和维护。

总的来说,预编译SQL是一种非常有效的数据库查询技术,它可以提高查询的性能,防止SQL注入攻击,并提高代码的可读性和可维护性。

是否有过MySQL调优经验?开发中使用过哪些调优工具?★

关于MySQL调优的常见方法和工具。

  1. 优化查询语句:查询语句的优化是最直接、最有效的调优方法。例如,尽量避免全表扫描,合理使用索引,避免在列上进行计算等。
  2. 使用Explain分析查询:Explain可以帮助我们理解MySQL如何执行SQL语句,从而找出性能瓶颈并进行优化。
  3. 调整MySQL配置:根据硬件资源和业务特性,合理调整MySQL的配置参数,例如InnoDB的缓冲池大小,日志文件大小等。
  4. 使用性能分析工具:例如MySQL自带的Performance Schema,可以提供丰富的性能诊断信息;MySQLTuner和Percona Toolkit等第三方工具,可以帮助分析MySQL的性能并给出优化建议。
  5. 使用索引优化查询:合理的索引可以极大地提高查询性能。但是,索引并不是越多越好,过多的索引会影响写入性能。
  6. 优化数据表结构:例如,选择合适的数据类型,避免NULL值等。

*注:具体调优和治理慢SQL大同小异,可见如下:*

如何监控线上环境中执行比较慢的SQL?☆

监控线上环境中执行比较慢的SQL,通常可以通过以下几种方式:

  1. 慢查询日志(Slow Query Log):MySQL提供了慢查询日志功能,可以记录查询执行时间超过指定阈值的SQL语句。你可以通过配置"long_query_time"参数来设置这个阈值。慢查询日志还可以记录没有使用索引的查询。这是一个非常有用的工具,可以帮助你找出那些需要优化的慢查询。(常用)
  2. 性能模式(Performance Schema):MySQL的性能模式是一个用于监控MySQL服务器运行时情况的功能。它可以提供丰富的性能诊断信息,包括SQL语句的执行时间,等待事件等。你可以通过查询性能模式的相关表来获取这些信息。
  3. 第三方监控工具:有许多第三方监控工具可以帮助你监控MySQL的性能,如Percona Monitoring and Management (PMM),Zabbix等。这些工具通常提供了丰富的监控指标和友好的界面,可以帮助你更好地理解和优化你的数据库性能。(每个公司一般都有自己封装的工具,让面试官知道你能想到这点就行了)
  4. SHOW PROCESSLIST命令:这个命令可以显示当前MySQL中正在执行的所有进程信息,包括SQL语句,执行时间等。这是一个简单但有用的工具,可以帮助你快速发现正在执行的慢查询。(常用)

如何治理一条慢SQL?★

分析一条慢SQL的主要步骤通常包括以下几个:

  1. 确定SQL是否真的慢:首先,你需要确定这条SQL是否真的执行慢,或者是由于其他因素(如网络延迟,系统负载等)导致的。你可以通过查看慢查询日志,或者使用SHOW PROCESSLIST 命令来确认。
  2. 使用 EXPLAIN 分析 SQL:MySQL的EXPLAIN命令可以帮助你理解MySQL如何执行一条SQL。它可以显示出SQL执行的详细步骤,包括使用的索引,扫描的行数等。通过分析EXPLAIN的输出,你可以找出SQL执行慢的原因。
  3. 检查索引:如果EXPLAIN显示SQL没有使用索引,或者使用了不合适的索引,那么你可能需要调整表的索引。你可以使用SHOW INDEX命令来查看表的索引信息。
  4. 检查表结构:如果表的结构设计不合理,也可能导致SQL执行慢。例如,数据类型选择不合适,或者表中包含大量NULL值等。你可以使用SHOW CREATE TABLE命令来查看表的结构。
  5. 优化SQL:根据以上分析,你可能需要对SQL进行优化。这可能包括改变查询的方式,添加或修改索引,调整表结构等。
  6. 监控SQL执行情况:在优化SQL后,你需要继续监控SQL的执行情况,以确认优化是否有效。

如何治理优化慢SQL?

1、数据库架构优化:数据库架构优化是一个复杂的过程,涉及到硬件、网络、数据库设计、查询优化等多个方面。以下是一些常见的优化策略:

硬件优化:提升硬件性能是最直接的优化手段,如增加内存、使用更快的硬盘(如SSD)、增加CPU核心数等。

  • 网络优化:优化网络设备和网络设置,减少网络延迟,提高网络吞吐量。
  • 数据库设计优化:如前面提到的表结构优化、索引优化等。
  • 查询优化:优化SQL查询,避免全表扫描,减少JOIN操作,使用索引等。
  • 分区和分表:对大表进行分区或分表,可以提高查询效率,减少锁竞争。

水平分库分表:当单表数据量过大时,可以将数据按照某种规则(如ID范围或哈希值)分散到多个数据库或表中,减少单个数据库或表的压力。

  • 垂直分库分表:将一张宽表按照列划分为多个表,每个表包含部分列,可以减少单次查询需要扫描的数据量。

读写分离:将读操作和写操作分开,分别在不同的服务器上执行,可以提高系统的并发处理能力,有效提高读取性能,同时降低单个服务器的压力。

  • 数据库复制:通过主从复制,可以将读取压力分散到多个从库上,主服务器处理写操作,从服务器处理读操作,提高读写性能。
  • 使用缓存:使用缓存可以减少数据库的I/O操作,提高系统性能。
  • 数据库参数调优:根据系统的实际情况,调整数据库的参数设置,如内存分配、连接数、线程数等。

2、索引优化

找出需要优化的SQL

查看慢查询日志:找出执行时间长的SQL语句。

使用性能监控工具:找出频繁执行或者资源消耗大的SQL语句。

查看执行计划:使用EXPLAIN或其他相关命令,查看SQL的执行计划,分析是否使用了索引,以及索引的使用情况。

分析和优化索引:定期通过性能监控工具,查看索引的使用情况,如命中率、扫描次数等,以评估索引的效果。

创建合适的索引:根据查询需求,创建合适的单列索引和复合索引,提高查询性能;

如:对于经常作为查询条件的字段,应该创建索引。对于经常参与排序的字段,可以创建排序索引。根据SQL查询的WHERE子句和JOIN条件,创建合适的索引。例如,如果经常根据某一列进行查询,那么可以为这一列创建索引。

优化索引设计:根据执行计划的分析结果,调整索引。如果SQL使用的索引不合适,可以考虑调整索引的列或者顺序。

如果一个表有多个索引,那么可能会导致写操作变慢,因为每次插入、更新或删除记录时,都需要更新所有的索引。因此,可以考虑合并多个单列索引为一个多列索引,或者删除不常用的索引。

  • 删除冗余和无用的索引:如果某个索引没有被查询使用,或者与其他索引有大量重叠,可以考虑删除该索引,以减少索引维护的开销。
  • 避免过多的索引:每个额外的索引都会增加写入的成本,因此应该避免创建不必要的索引。
  • 使用覆盖索引:如果一个查询可以通过索引获取所有需要的数据,那么这个查询就可以避免访问表(回表),可以直接从索引中获取数据,大大提高查询效率。
  • 使用索引提示:在某些情况下,数据库的查询优化器可能没有选择最优的索引,这时可以使用索引提示来强制使用某个索引。
  • 维护索引:定期进行索引维护,以平衡索引带来的插入、删除和更新的开销。
  • 避免索引失效,如:使用 EXPLAIN 分析执行计划
    • 使用非等值查询:索引主要用于等值查询和范围查询。如果使用非等值查询(如<>,!=),则索引可能无法使用。
    • 在列上使用函数或表达式:如果在列上使用函数或表达式(如UPPER(column),column+1),则索引可能无法使用。
    • 使用OR连接的查询条件:如果使用OR连接的查询条件,并且每个条件都涉及到索引列,那么索引可能无法使用。
    • 使用LIKE查询,并且通配符在前:如果使用LIKE查询,并且通配符在前(如LIKE '%abc'),则索引可能无法使用。
    • 数据类型不匹配:如果查询条件中的数据类型与列的数据类型不匹配,那么索引可能无法使用。
    • 索引列的选择性差:如果索引列的值过于集中,或者重复值过多(如性别、是否删除等字段),那么即使有索引,数据库优化器也可能选择全表扫描而不是使用索引。
    • 小表查询:如果表的记录数很少,数据库优化器可能会选择全表扫描而不是使用索引,因为全表扫描在这种情况下可能更快。
  • 考虑硬件和系统配置:索引的效果也会受到硬件性能和系统配置的影响,如内存大小、磁盘性能、数据库参数设置等,需要综合考虑。
    • 硬件性能:内存大小、磁盘性能等都会影响索引的效果。
    • 系统配置:数据库的参数设置,如缓存大小、IO策略等,也会影响索引的效果。

3、表结构优化

  • 数据类型选择:选择合适的数据类型(空间小,足够存即可),可以减少存储空间,提高查询性能。
  • 合理设计主键:主键应尽量选择较短的数据类型,如整型,避免使用字符串类型,这样可以提高查询效率。
  • 划分表:如果一个表的数据量非常大,可以考虑进行分表,如按日期分表、按区域分表等,这样可以提高查询效率。
  • 使用视图:如果有复杂的查询,可以考虑使用视图,将复杂查询的结果保存为一个视图,这样查询时只需要查询视图即可,可以提高查询效率。
  • 使用存储过程和触发器:如果有复杂的业务逻辑,可以考虑使用存储过程和触发器,将业务逻辑封装在数据库中,这样可以减少网络传输,提高效率。
  • 优化字段顺序:将经常一起查询的字段放在一起,可以提高磁盘I/O效率。
  • 避免NULL:尽量避免使用NULL,因为NULL会使索引、查询优化等复杂化,同时也会占用更多的存储空间。

4、SQL语句优化

  • 使用索引:合理使用索引可以大大提高查询效率。但是,索引并不是越多越好,过多的索引会增加写操作的开销。
  • 避免全表扫描:全表扫描的开销很大,应尽量避免。可以通过使用索引、减少返回的数据量等方式来避免全表扫描。
  • 减少数据的返回量:只返回需要的数据,避免返回不必要的数据。
  • 避免在WHERE子句中使用函数或计算:这样会导致索引失效,降低查询效率。
  • 使用JOIN代替子查询:在一些情况下,使用JOIN可以提高查询效率。
  • 使用批量插入或更新:批量插入或更新比单条插入或更新效率更高。
  • 使用预编译语句:预编译语句可以减少SQL解析的次数,提高执行效率。
  • 优化分页查询:对于大数据量的分页查询,可以使用ID范围查询等方式优化。
  • 避免使用SELECT *:只选择需要的列,可以减少网络传输的数据量,提高效率。
  • 使用EXPLAIN分析查询:通过EXPLAIN命令,可以查看查询的执行计划,找出性能瓶颈

5、锁带来的慢SQL:

  1. 分析锁等待和死锁:通过数据库提供的工具,可以分析锁等待和死锁情况,找出问题并进行优化。
  2. 优化SQL语句:尽量减少单个事务锁定的行数,避免全表扫描,尽量使用索引,减少锁的竞争。
  3. 调整事务隔离级别:事务隔离级别越高,数据一致性越好,但并发性能越低。可以根据实际需要,适当降低事务隔离级别,减少锁的竞争。
  4. 控制事务大小:尽量避免长事务,因为长事务会持有锁的时间长,增加锁冲突的可能性。可以通过控制事务的大小,将大事务拆分成多个小事务,减少锁竞争。
  5. 使用乐观锁:乐观锁在数据更新时才检查版本冲突,可以在并发冲突较少的情况下,提高系统的并发能力。
  6. 锁超时设置:通过设置锁的超时时间,可以避免长时间等待锁。

6、数据库设计优化

  • 数据库的正规化:通过消除数据冗余和依赖,可以提高数据的一致性和完整性,但可能会牺牲查询性能。
  • 数据库的反规范化:在保持数据一致性和完整性的前提下,通过增加数据冗余,可以提高查询性能。

7、事务管理优化

  • 并发控制:通过合理的事务隔离级别和锁策略,可以提高并发性能,减少死锁。
  • 日志管理:通过合理的日志策略,可以提高事务的性能,同时保证数据的可恢复性。

注:说到这差不多可以了,后面我也不太熟悉,不过还是列举了大概方向,面试可以提及,说明自己不太了解但知道即可

1、优化器优化:

  • 调整优化器参数:根据数据和查询特性,调整优化器参数,可以帮助优化器做出正确的决策。
  • 使用查询提示:查询提示可以影响优化器的决策,提高查询性能。
  • 更新统计信息:定期更新统计信息,可以帮助优化器做出正确的决策。

2、内存池优化:

  • 调整内存池大小:根据系统的内存容量和数据库的需求,调整内存池的大小,可以优化内存使用。
  • 调整其他内存参数:根据数据和查询特性,调整其他内存参数,可以提高查询性能。

3、磁盘文件优化:

  • 分散磁盘I/O负载:通过合理的文件和目录布局,可以分散磁盘I/O负载,提高磁盘I/O性能。
  • 使用SSD硬盘:SSD硬盘的读写速度比传统硬盘快,可以提高磁盘I/O性能。

4、数据库运维优化:

  • 监控:通过监控数据库的性能指标,可以及时发现和解决性能问题。
  • 备份和恢复:通过合理的备份和恢复策略,可以保证数据的可用性和安全性。

5、硬件选择优化:

  • CPU:选择合适的CPU,可以提高数据库的计算性能。
  • 内存:选择足够的内存,可以提高

如何查看当前SQL使用了哪个索引?

同上述问题,Explain使用

索引如何进行分析和调优?

1、找出需要优化的SQL

  • 查看慢查询日志:找出执行时间长的SQL语句。
  • 使用性能监控工具:找出频繁执行或者资源消耗大的SQL语句。

2、查看执行计划:使用EXPLAIN或其他相关命令,查看SQL的执行计划,分析是否使用了索引,以及索引的使用情况。

3、分析和优化索引:定期通过性能监控工具,查看索引的使用情况,如命中率、扫描次数等,以评估索引的效果。

4、创建合适的索引:根据查询需求,创建合适的单列索引和复合索引,提高查询性能;

  • 如:对于经常作为查询条件的字段,应该创建索引。对于经常参与排序的字段,可以创建排序索引。
  • 根据SQL查询的WHERE子句和JOIN条件,创建合适的索引。例如,如果经常根据某一列进行查询,那么可以为这一列创建索引

5、优化索引设计:根据执行计划的分析结果,调整索引。如果SQL使用的索引不合适,可以考虑调整索引的列或者顺序。

  • 如果一个表有多个索引,那么可能会导致写操作变慢,因为每次插入、更新或删除记录时,都需要更新所有的索引。因此,可以考虑合并多个单列索引为一个多列索引,或者删除不常用的索引。
  • 删除冗余和无用的索引:如果某个索引没有被查询使用,或者与其他索引有大量重叠,可以考虑删除该索引,以减少索引维护的开销。
  • 避免过多的索引:每个额外的索引都会增加写入的成本,因此应该避免创建不必要的索引。
  • 使用覆盖索引:如果一个查询可以通过索引获取所有需要的数据,那么这个查询就可以避免访问表(回表),可以直接从索引中获取数据,大大提高查询效率。
  • 使用索引提示:在某些情况下,数据库的查询优化器可能没有选择最优的索引,这时可以使用索引提示来强制使用某个索引。
  • 维护索引:定期进行索引维护,以平衡索引带来的插入、删除和更新的开销。
  • 避免索引失效,如:使用 EXPLAIN 分析执行计划
    • 使用非等值查询:索引主要用于等值查询和范围查询。如果使用非等值查询(如<>,!=),则索引可能无法使用。
    • 在列上使用函数或表达式:如果在列上使用函数或表达式(如UPPER(column),column+1),则索引可能无法使用。
    • 使用OR连接的查询条件:如果使用OR连接的查询条件,并且每个条件都涉及到索引列,那么索引可能无法使用。
    • 使用LIKE查询,并且通配符在前:如果使用LIKE查询,并且通配符在前(如LIKE '%abc'),则索引可能无法使用。
    • 数据类型不匹配:如果查询条件中的数据类型与列的数据类型不匹配,那么索引可能无法使用。
    • 索引列的选择性差:如果索引列的值过于集中,或者重复值过多(如性别、是否删除等字段),那么即使有索引,数据库优化器也可能选择全表扫描而不是使用索引。
    • 小表查询:如果表的记录数很少,数据库优化器可能会选择全表扫描而不是使用索引,因为全表扫描在这种情况下可能更快。

6、考虑硬件和系统配置:索引的效果也会受到硬件性能和系统配置的影响,如内存大小、磁盘性能、数据库参数设置等,需要综合考虑。

  1. 硬件性能:内存大小、磁盘性能等都会影响索引的效果。
  2. 系统配置:数据库的参数设置,如缓存大小、IO策略等,也会影响索引的效果。

EXPLAIN关键字中的重要指标有哪些?

优化器为什么会在多个索引中选择一条?

优化器在多个索引中选择一条的原因主要是为了提高查询效率。优化器会根据查询语句和现有的索引,预测使用哪个索引能够获取最快的查询结果。这个预测过程主要基于以下几个因素:

  1. 索引的选择性:选择性是指索引中不同值的数量与表中记录数量的比例。选择性越高,优化器越可能选择该索引。因为高选择性的索引能够更精确地定位到表中的记录。
  2. 索引类型:不同类型的索引适用于不同类型的查询。例如,B-tree索引适用于范围查询,Hash索引适用于等值查询。优化器会根据查询类型选择合适的索引。
  3. 查询语句:查询语句中的条件和排序也会影响索引的选择。例如,如果查询条件中有多个字段,优化器可能会选择覆盖更多字段的索引。
  4. 表的数据分布:如果表的数据分布不均,优化器可能会选择能够更好地处理数据分布的索引。

优化器的目标是选择能够最快返回查询结果的索引。但是,优化器的预测并不总是准确的,有时候可能需要手动指定索引或者调整索引以获取更好的查询性能。

MySQL数据库 CPU 飙升的话你会如何分析?☆

MySQL数据库CPU飙升可能是由多种原因造成的,常见方法:

  1. 查看慢查询日志:慢查询日志可以帮助我们找到执行时间较长的SQL语句,这些语句可能是导致CPU飙升的原因。
  2. 查看并优化SQL语句:使用EXPLAIN命令查看SQL语句的执行计划,看是否有可以优化的地方,如添加索引,改写SQL语句等。
  3. 查看并调整系统参数:MySQL的一些系统参数设置不合理也可能导致CPU飙升,如查询缓存大小、排序缓存大小等,可以通过SHOW VARIABLES命令查看系统参数,然后根据实际情况进行调整。
  4. 查看并调整硬件配置:如果硬件配置不足,也可能导致CPU飙升,可以考虑升级硬件,如增加CPU核数,提高CPU频率等。
  5. 查看并优化数据库结构:如果数据库结构设计不合理,如数据冗余过多,没有合适的索引等,也可能导致CPU飙升,可以考虑优化数据库结构。
  6. 查看并调整并发设置:如果并发设置不合理,如连接数过多,线程数过多等,也可能导致CPU飙升,可以通过SHOW STATUS命令查看并发情况,然后根据实际情况进行调整。

有没有进行过分库分表?★什么是分库分表?什么时候进行分库分表?

分库分表是数据库设计中的一种常见策略,主要用于解决单一数据库或表数据量过大,查询性能下降的问题。分库是指将数据分布到多个数据库中,分表是指将一个表的数据分布到多个表中。

分库分表有两种常见的策略:

  1. 垂直分库分表:按业务模块将数据分布到不同的数据库或表中,每个数据库或表存储相关的业务数据。这种策略可以减少业务之间的数据交互,提高查询性能。
  2. 水平分库分表:按数据的某个字段(如ID)的值将数据分布到不同的数据库或表中,每个数据库或表存储部分数据。这种策略可以将大表分解为多个小表,提高查询性能。

进行分库分表的时机主要取决于以下几个因素:

  1. 数据量:如果单一数据库或表的数据量过大,查询性能下降,可以考虑进行分库分表。
  2. 业务需求:如果业务需求变更,需要对数据进行复杂的查询和处理,可以考虑进行分库分表。
  3. 系统性能:如果系统性能下降,数据库成为瓶颈,可以考虑进行分库分表。
  4. 数据安全:如果需要提高数据的安全性,可以通过分库分表将数据分布到不同的服务器或存储设备中。

分库分表可以提高数据库的查询性能和数据的安全性,但是也会增加系统的复杂性,需要更复杂的数据维护和管理策略。因此,进行分库分表的决定需要根据实际情况进行权衡。

注:关于分库分表详情见分布式篇

有没有配合es使用经验?

MySQL和Elasticsearch结合使用一般出现在以下几种业务场景中:

  1. 全文搜索:MySQL的全文搜索功能相对较弱,而Elasticsearch在全文搜索方面表现优秀,支持多种语言,可以进行模糊查询、同义词查询等复杂的文本处理。例如,在电商网站中,用户可以通过输入关键词搜索商品,这就需要用到全文搜索。
  2. 日志分析:Elasticsearch常被用于日志收集和分析。在这种场景下,MySQL可以用来存储业务数据,而Elasticsearch用来存储和分析日志数据。
  3. 实时统计和分析:Elasticsearch支持实时统计和分析,可以快速对大量数据进行聚合操作。例如,在社交网络或者新闻网站中,可以实时统计用户的点击量、评论量等。
  4. 地理位置搜索:Elasticsearch支持地理位置数据的索引和搜索,可以用来实现基于地理位置的搜索和推荐。例如,在外卖或者打车应用中,可以根据用户的位置来推荐附近的餐厅或者司机。
  5. 数据可视化:Elasticsearch与Kibana结合,可以方便地对数据进行可视化展示,用于业务报表或者数据分析。

使用中存在的问题:

  1. 数据同步:MySQL和Elasticsearch的数据同步通常需要依赖第三方工具。例如,Logstash是Elasticsearch官方提供的一个开源数据收集引擎,它支持从多种数据源(包括MySQL)中提取数据,然后将数据发送到多种存储系统(包括Elasticsearch)中。Logstash的JDBC插件可以定时从MySQL中抽取数据,然后写入Elasticsearch。
  2. 数据模型设计:Elasticsearch是一个基于Lucene的搜索服务器,它提供了全文搜索、Hit highlighting、Faceted search、Real-time indexing等功能。在Elasticsearch中,数据被存储在索引中,索引由一个或多个分片组成,每个分片是一个自包含的索引。因此,你需要根据搜索和分析的需求来设计数据模型,例如,你可以将MySQL中的一对多或多对多关系扁平化,以便在Elasticsearch中进行高效查询。
  3. 数据更新:当MySQL中的数据更新时,你需要将这些更新同步到Elasticsearch中。你可以使用MySQL的binlog来捕获数据的变化,然后将这些变化应用到Elasticsearch中。或者,你也可以定时轮询MySQL,检查数据的变化。
  4. 查询优化:Elasticsearch提供了强大的查询功能,但并不是所有的查询都是高效的。例如,全文搜索虽然功能强大,但性能较低。因此,你需要根据Elasticsearch的特性来优化查询,例如,尽量避免使用全文搜索,使用更高效的term查询或者range查询。
  5. 数据一致性:由于数据是异步同步到Elasticsearch的,所以你需要处理数据一致性问题。例如,你可以使用版本号或者时间戳来确保数据的一致性。当MySQL和Elasticsearch中的数据不一致时,你可以根据版本号或者时间戳来判断哪个是最新的数据。
  6. 数据备份和恢复:虽然Elasticsearch本身具有一定的容错能力,但为了防止数据丢失,你还需要定期备份Elasticsearch的数据。同时,你也需要制定数据恢复的策略,以便在数据丢失时能够快速恢复。

有哪些常见分库分表工具?说一下实现分库分表工具的实现思路?

分库分表的工具有很多,例如:MyCat、Sharding-JDBC、Sharding-Sphere、TDDL等。

这些工具的实现思路主要包括以下几个步骤:

  1. 分片策略:首先,需要定义分片策略,即如何将数据分布到不同的数据库或表中。常见的分片策略包括范围分片、哈希分片、列表分片等。
  2. 路由计算:根据分片策略,工具会计算出每个查询或更新操作应该路由到哪个数据库或表。这个过程通常是在应用程序发出数据库操作请求时进行的。
  3. 数据操作:工具会将数据库操作请求路由到正确的数据库或表,然后执行操作。如果一个操作需要在多个数据库或表中执行,工具可能需要进行分布式事务管理。
  4. 结果合并:如果一个查询操作在多个数据库或表中执行,工具需要将各个数据库或表的结果合并后返回给应用程序。

说一下读写分离常见方案?

读写分离是数据库架构中的一种常见策略,主要目的是提高数据库的性能和可用性。下面是一些常见的读写分离方案:

  1. 主从复制:这是最常见的读写分离方案。在这种方案中,有一个主数据库进行写操作,然后将写操作的日志复制到一个或多个从数据库。读操作可以在任何数据库上进行,但通常在从数据库上进行以减轻主数据库的负载。
  2. 数据库中间件:数据库中间件如MyCat、Cobar等可以实现读写分离。中间件位于应用服务器和数据库服务器之间,根据SQL语句的类型(读或写)将请求路由到不同的数据库。
  3. 负载均衡器:负载均衡器如LVS、HAProxy等也可以实现读写分离。负载均衡器可以根据请求的类型和负载情况将请求路由到不同的数据库。
  4. 代理服务器:代理服务器如MySQL Proxy、MaxScale等可以实现读写分离。代理服务器在应用服务器和数据库服务器之间,可以根据SQL语句的类型将请求路由到不同的数据库。
  5. 应用程序:应用程序也可以实现读写分离。在这种方案中,应用程序需要知道哪些操作是读操作,哪些操作是写操作,并将它们路由到不同的数据库。

结合场景分析:

  1. 主从复制:适用于读多写少的业务场景,例如新闻网站、博客网站等。通过主从复制,可以将读操作的负载分散到多个从数据库,从而提高系统的读性能。
  2. 数据库中间件:适用于需要进行复杂数据库操作的业务场景,例如电商网站、社交网站等。数据库中间件可以提供一些高级功能,例如分库分表、读写分离、事务管理等。
  3. 负载均衡器:适用于需要处理大量并发请求的业务场景,例如视频网站、游戏网站等。负载均衡器可以将请求均匀地分散到多个数据库,从而提高系统的并发处理能力。
  4. 代理服务器:适用于需要进行复杂数据库操作,但又不想在应用程序中处理这些操作的业务场景。代理服务器可以将复杂的数据库操作封装起来,让应用程序可以像操作单一数据库一样进行操作。
  5. 应用程序:适用于需要进行定制化数据库操作的业务场景。在应用程序中实现读写分离可以给开发者最大的灵活性,但也需要开发者对数据库操作有深入的理解。

某个表有数千万数据,查询比较慢,如何优化?说一下思路?★

处理数千万级别的大数据表,查询优化是一个复杂的过程,通常需要从以下几个方面进行考虑(基本优化思考,具体还看场景):

  1. 索引优化:为表中的关键列创建索引,可以显著提高查询性能。但是,索引并非越多越好,过多的索引会增加写操作的开销并占用更多的存储空间。
  2. SQL语句优化:优化查询语句,避免全表扫描,尽量减少JOIN操作,避免在WHERE子句中使用!=或<>操作符,避免在WHERE子句中对字段进行NULL值判断等。
  3. 分表分库:如果一个表的数据量过大,可以考虑进行分表或分库操作。分表可以将一个大表分成多个小表,分库可以将数据分布到多个数据库中。
  4. 读写分离:通过主从复制或其他方式实现读写分离,可以提高查询性能。
  5. 使用缓存:将常用的查询结果存储在缓存中,可以避免频繁地进行数据库查询。
  6. 硬件升级:如果上述方法都无法满足需求,可能需要考虑升级硬件,例如增加内存、使用更快的硬盘等。

*注意:具体优化项做法可参考上述 慢SQL 优化,此处不在赘述*

如果有超大分页该怎么处理?☆

对于超大分页的处理,传统的 LIMIT offset, rows 的方式会随着 offset 的增大而导致性能下降,因为数据库需要跳过 offset 指定的行数,这在数据量大的时候会非常耗时。以下是一些处理超大分页的策略:

  1. 记住上一次的位置:这种方式适用于数据更新不频繁,且可以按照某个唯一键顺序排列的情况。比如,我们可以记住上一页的最后一个 ID,下一页就从这个 ID 开始取,而不是从头开始扫描。
  2. 索引覆盖:如果分页的字段已经建立了索引,那么可以直接通过索引进行分页,这样可以避免全表扫描,提高查询效率。
  3. 数据预处理:可以将需要分页的数据预先处理,比如预先计算好每一页的数据范围,存储在另一张表中,查询时直接查这张表。
  4. 使用搜索引擎:对于全文检索或者复杂查询,可以使用搜索引擎如 Elasticsearch 进行处理,它们对大数据量的分页处理更优。
  5. 分批查询:对于超大数据量,可以采用分批查询的方式,每次查询一部分数据,处理完后再查询下一部分。

以上策略可以根据实际情况和业务需求进行选择和组合使用。

MySQL服务器毫无规律的异常重启如何排查问题?

MySQL服务器无规律的异常重启可能是由多种原因引起的,以下是一些常见的排查步骤:

  1. 查看错误日志:MySQL的错误日志通常是排查问题的第一步。你可以在这里找到关于MySQL重启的信息,包括重启的原因、时间以及其他相关的错误信息。
  2. 检查系统资源:如果MySQL服务器的资源(如CPU、内存、磁盘空间)使用过高,可能会导致MySQL服务器重启。你可以使用系统监控工具(如top、htop、vmstat、iostat等)来检查系统资源的使用情况。
  3. 检查MySQL配置:MySQL的配置错误也可能导致服务器重启。例如,如果设置的内存使用超过了实际可用的内存,MySQL可能会因为无法获取足够的内存而重启。
  4. 检查硬件问题:硬件故障或者硬件资源不足也可能导致MySQL服务器重启。例如,如果服务器的电源供应不稳定,或者硬盘有坏道,都可能导致服务器重启。
  5. 检查网络问题:网络问题也可能导致MySQL服务器重启。例如,如果网络连接不稳定,或者网络带宽不足,都可能影响MySQL的正常运行。
  6. 查看系统日志:系统日志可能会记录一些MySQL重启的相关信息,通过查看系统日志,可能会找到一些线索。

MySQL线上修改表结构有哪些风险?

在MySQL线上环境中修改表结构可能会带来一些风险,主要包括以下几点:

  1. 性能影响:修改表结构通常需要对表进行锁定,这期间可能会阻塞对该表的读写操作,对性能有一定影响。如果是大表,这个过程可能会持续很长时间。
  2. 数据丢失:如果在修改表结构的过程中出现错误,可能会导致数据丢失。例如,如果在修改表结构时不小心删除了某个字段,那么该字段的所有数据都会丢失。
  3. 兼容性问题:修改表结构可能会导致应用程序的兼容性问题。例如,如果删除或更改了某个字段,那么依赖这个字段的应用程序可能会出现问题。
  4. 事务中断:如果在事务中修改表结构,可能会导致事务被中断,影响业务的正常运行。

因此,在线上环境中修改表结构时,需要谨慎操作,最好在测试环境中先进行测试,确认无误后再在线上环境中执行。同时,也需要做好数据备份,以防万一