some面试题3

1. MyBatis 中 #{}${} 的区别总结


✅ 一、基本区别

对比项 #{} ${}
含义 预编译参数占位符 字符串直接替换
底层机制 使用 JDBC 的 PreparedStatement 使用 JDBC 的 Statement
SQL 注入 安全,防止注入 不安全,易被注入攻击
是否加引号 是(自动处理字符串类型) 否(原样插入)
参数处理方式 参数化查询,绑定参数 直接拼接到 SQL 中
性能优化 支持预编译缓存,性能更好 每次生成新 SQL,影响性能

✅ 二、原理说明

#{}:参数化查询

  • MyBatis 将 #{} 替换为 ? 占位符。
  • 使用 PreparedStatement 设置参数值(如 setString()setInt())。
  • 数据库在执行时将参数与 SQL 分离处理,有效防止 SQL 注入。

示例:

SELECT * FROM users WHERE name = #{name}
-- 实际生成:SELECT * FROM users WHERE name = ?
-- 然后通过 setString(1, "Tom") 赋值

${}:字符串拼接

  • MyBatis 直接将变量内容替换到 SQL 中。
  • 类似于 Java 中的字符串拼接:"SELECT * FROM " + tableName;
  • 如果用户输入未经校验,容易造成 SQL 注入。

示例:

SELECT * FROM ${tableName} WHERE id = 1
-- 若 tableName = "users; DROP TABLE users"
-- 则生成:SELECT * FROM users; DROP TABLE users WHERE id = 1

✅ 三、使用建议(最佳实践)

场景 推荐用法 原因
查询、插入、更新等常规操作 #{} 安全、高效、防注入
动态表名、列名、排序字段等 ${}(慎用) 必须拼接 SQL 片段时使用
用户输入内容 必须使用 #{} 防止 SQL 注入攻击

✅ 四、一句话总结

  • #{} 是安全的、参数化的写法,应优先使用;
  • ${} 是危险的、原始的拼接方式,只在必要时使用,并做好安全校验。

2. mysql优化

为了详细说明 MySQL 数据库优化策略,我们将从几个关键领域进行探讨:硬件和操作系统、MySQL 配置、查询优化、数据库结构设计以及应用层优化。每个方面都包含了一些具体的技术和方法,帮助你提高数据库的性能和可靠性。

2.1. 硬件优化

2.2. MySQL 配置优化

  • 调整缓冲区大小:
    • innodb_buffer_pool_size: 设置为系统总内存的 70%-80% 是一个常见的做法,特别是当主要使用 InnoDB 存储引擎时。
      SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
      单位是字节(约128MB)
    • key_buffer_size: 如果使用 MyISAM 表,这个参数控制索引块缓存的大小。

2.3. 查询优化

  • 索引优化:

    • 创建适当的索引是提高查询效率的关键。考虑列的选择性(唯一值的数量与总记录数的比例),为经常用于 WHERE 条件、JOIN 的列创建索引。
    • 使用复合索引时,注意索引列的顺序,通常将最常用于过滤条件的列放在前面。
  • EXPLAIN 分析查询:

    • 利用 EXPLAIN 关键字来查看 SQL 执行计划,理解 MySQL 如何执行你的查询,识别潜在的性能瓶颈。
  • 避免全表扫描:

    • 尽量保证查询条件能够利用索引,通过添加合适的索引来减少全表扫描的情况。

2.4. 数据库结构优化

  • 规范化与反规范化:

    • 在保证数据一致性的前提下,有时需要对某些表进行反规范化处理,比如合并一些关联紧密但需要频繁联合查询的表,以减少复杂的 JOIN 操作。
  • 选择合适的数据类型:

    • 使用最小化但足够的数据类型,例如使用 INT 而不是 BIGINT,VARCHAR 而不是 TEXT,这不仅可以节省空间,还能加快查询速度。

2.5. 应用层优化

  • 批量操作:

    • 尽量减少单条记录的操作次数,采用批量插入或更新的方式,降低数据库的负载。
  • 缓存机制:

    • 引入缓存机制(如 Redis ),可以在不直接访问数据库的情况下提供快速的数据访问服务。
  • 异步处理:

    • 对于耗时较长的操作,考虑采用消息队列等方式实现异步处理,减轻数据库压力。

2.6. 定期维护

  • 碎片整理:
    • 定期运行 OPTIMIZE TABLE 命令来重新组织表数据和相关索引的物理存储,消除由于频繁增删改造成的存储碎片。
      表复制(类似 ALTER TABLE ... FORCE),重建聚簇索引
      InnoDB 使用 页(Page) 作为存储的基本单位,默认大小是 16KB

当发生以下情况时,页内会出现碎片:

  1. 行被删除 → 页中留下空隙;
  2. 行被更新为更长的内容 → InnoDB 需要将整行迁移到新的页中,旧页留下空隙;
  3. 页分裂(Page Split) → 插入新记录时页已满,需要拆分页,导致空间利用率下降。
    SHOW TABLE STATUS LIKE 'your_table_name';

3. 索引创建原则

创建索引是数据库优化的重要手段之一,但并不是所有的索引都能带来性能的提升。合理的索引设计需要考虑多个因素,以确保既能提高查询效率,又能避免不必要的开销。以下是索引创建的一些基本原则:

1. 选择性原则

  • 高选择性:索引字段的选择性越高(即不同值的数量与总记录数的比例越大),索引的效果越好。例如,主键或唯一键通常具有很高的选择性。
  • 低基数字段不适合建立索引:如性别、状态等只有少数几个可能值的字段,除非这些字段经常出现在复杂的查询条件中。

2. 覆盖索引(Covering Index)

  • 如果一个索引包含了查询所需的所有列,则称为覆盖索引。使用覆盖索引可以避免“回表”操作,直接从索引中获取数据,极大提高了查询效率。

3. 前缀索引

  • 对于较长的字符串字段,可以考虑创建前缀索引而不是整个字段的索引,以减少索引占用的空间。但是需要注意选择合适的前缀长度,保证足够的选择性。

4. 组合索引(Composite Index)

  • 当多个列经常一起出现在查询条件中时,可以考虑创建组合索引。组合索引要注意列的顺序,最常用的过滤条件应放在前面。

5. 避免过度索引

  • 每个索引都会增加插入、更新和删除操作的成本,因为每次修改数据时都需要同步更新索引。因此,应该根据实际需求合理创建索引,避免创建无用的索引。

6. 索引维护成本

  • 频繁更新的表上创建过多的索引会显著增加维护成本,降低写入性能。因此,在频繁写入的数据表上应谨慎添加索引。

7. 复合索引中的列顺序

  • 在复合索引中,列的顺序非常重要。一般来说,将选择性最高的列放在最前面,并且考虑到查询条件中最常出现的列。

8. 索引与排序/分组

  • 如果查询中包含 ORDER BYGROUP BY 子句,那么在这些列上创建索引可以帮助数据库更快地完成排序或分组操作。

9. 唯一索引

  • 对于那些要求数据唯一的列,应该创建唯一索引。这不仅能保证数据完整性,还能加速查询速度。

10. 全文索引

  • 对于需要进行全文搜索的文本字段,可以考虑使用全文索引(Full-text Index)。MySQL 提供了对 MyISAM 和 InnoDB 表的支持。

创建

CREATE TABLE ft_chn (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(255),
    body TEXT,
    FULLTEXT ( title , body ) WITH PARSER NGRAM
)  ENGINE=INNODB CHARACTER SET UTF8; 

CREATE FULLTEXT INDEX index_name ON table_name(column_name);

使用

select * from fts_a where match(body) against ('porridge' in natural language mode);

排序原理:
文档频率(Document Frequency, DF):指的是包含特定词语的文档数量。
逆文档频率(Inverse Document Frequency, IDF):是对文档频率的一种修正,用来衡量词语的重要性。如果某个词在很多文档中都出现,则其重要性较低;反之,如果只在少数文档中出现,则其重要性较高。

-es和全文索引“轻量级、小数据、简单查询、对英文支持较好ngram分词中文按字切分 → MySQL 全文索引;
重量级、大数据、复杂搜索 → Elasticsearch。”

11. 索引失效的情况

  • 使用函数、表达式处理索引列会导致索引失效。
  • LIKE 查询中使用通配符 % 开头也会导致索引无法被有效利用。
  • OR 条件下的索引使用情况复杂,有时可能导致索引失效。

实践建议

  • 定期分析现有索引的使用情况,移除不再使用的索引。
  • 利用 EXPLAIN 分析 SQL 执行计划,了解哪些索引被使用,哪些没有被使用。
  • 根据业务逻辑调整索引策略,比如在报表系统中可能会更倾向于读取优化,而在交易系统中则需平衡读写性能。

你可能感兴趣的:(java,sql)