MySQL 反模式与排查宝典

概述

衔接前文

本系列从 MySQL 分层架构出发,逐层深入 InnoDB 存储引擎的 B+Tree 索引原理、事务与 MVCC 机制、行锁与间隙锁实现、SQL 优化器决策逻辑、主从复制与 GTID 架构、分库分表与 ShardingSphere 内核、慢查询与性能诊断体系,以及连接管理与连接池全局协调策略。这些知识点构成了数据库稳定运行的完整理论底座。然而,知晓原理并不能保证在生产环境中正确应用------反模式往往潜藏在微小的配置偏差和日常编码习惯中,一旦触发,便会引发连锁故障。

本文作为系列收官之作,将前 9 篇的全部核心技术点投射到 26 个真实故障场景中,通过"反模式分析 → 故障排查 → 精准修复"的闭环,帮助读者将分散的知识点内化为系统化的排障直觉。全文严格遵循"错误示例 → 现象描述 → 排查思路 → 根因分析(显式映射前文原理与源码细节) → 修正方案 → 最佳实践"的六步诊断法,整合 MySQL 全工具链诊断矩阵与多层级标准化排查决策树,并与 JDBC 系列第 10 篇《JDBC 反模式与排查宝典》形成从应用到数据库的全链路排障闭环。

总结性引言

"CPU 飙高但 QPS 平稳""查询突然变慢但索引未变""主从延迟忽高忽低""Too many connections 突然爆发"------这些典型的 MySQL 线上故障,根源往往不是某个技术组件自身存在缺陷,而是使用方式违背了其设计本意。本文将 MySQL 生态中最常见、破坏力最大的反模式归纳为索引、SQL与查询、事务与锁、复制与架构、DDL与表设计、连接与配置 六大领域,每个领域进一步细分为设计反模式运行时反模式 两个子维度。26 个真实案例均采用标准六步诊断法逐层展开,每个案例的根因直接追溯到前文的具体原理甚至源码级细节。同时,本文还将 MySQL 内置诊断视图、performance_schemapt-query-digestEXPLAIN ANALYZE、PMM 以及 JDBC 端的 Arthas、连接池 Metrics 等工具编织成一张严密的全景排查网络,并绘制了覆盖四大核心故障类型的多层级标准化决策树。最后一章以 18 道高频面试故障排查题收束,与前 9 篇的原理面试题形成完整的知识验证闭环。

核心要点
  • 六大反模式领域(设计+运行时):索引、SQL、事务锁、复制架构、DDL 表设计、连接配置,共计 26 个真实案例。
  • 六步诊断法:错误示例→现象描述→排查思路→根因分析(显式关联前文原理与源码)→修正方案→最佳实践。
  • 全链路排查闭环:与 JDBC 系列第 10 篇跨系列联动,覆盖从 Java 应用到 MySQL 数据库的完整调用链。
  • 诊断工具集与决策树SHOW ENGINE INNODB STATUSsys schemaperformance_schemapt-query-digestEXPLAIN ANALYZE、PMM、Arthas、连接池 Metrics 等工具速查;四大典型故障的多层级标准化排查决策路径。
  • 面试故障排查专题:18 道真实故障场景题,每题附有详细的排查命令、日志解读、根因回溯与修复方案。

文章组织架构图

MySQL 反模式与排查宝典

  1. 索引反模式

  2. SQL 与查询反模式

  3. 事务与锁反模式

  4. 复制与架构反模式

  5. DDL 与表设计反模式

  6. 连接与配置反模式

  7. 诊断工具集与工具→现象映射表

  8. 多层级标准化排查决策树

  9. 面试高频故障排查专题

设计反模式

运行时反模式

冗余索引与重复索引

复合索引列顺序错误

隐式类型转换致索引失效

LIKE前缀通配致索引失效

索引统计信息过时选错索引

设计反模式

运行时反模式

SELECT * 导致覆盖索引失效

ORDER BY RAND 导致全表扫描

深度分页 LIMIT offset,size

子查询未物化致依赖子查询

Join 驱动表选择错误

设计反模式

运行时反模式

事务边界过大含外部I/O

长事务阻塞Purge致Undo膨胀

无索引UPDATE致全表加锁

不同顺序访问资源致死锁

RR下未用SELECT FOR UPDATE

设计反模式

运行时反模式

STATEMENT格式Binlog致不一致

主从延迟致读写分离读旧数据

分片键选择不当致数据倾斜

设计反模式

运行时反模式

滥用外键致级联锁与死锁

直接ALTER TABLE致锁表

VARCHAR过大致行溢出页过多

设计反模式

运行时反模式

max_connections未预估增长

maxLifetime > wait_timeout致静默断连

idleTimeout不当致Sleep堆积

connect_timeout与连接池不协调

MySQL端全工具链速查

JDBC端工具链整合

工具→现象映射表不少于12行

慢查询突增但SQL未变决策分支

锁等待与死锁激增决策分支

主从延迟持续增大决策分支

连接数耗尽与Too many connections决策分支

架构图说明

总览说明

全文共 9 个模块,以前 6 个反模式领域的 26 个真实案例为主体,每个案例均从设计反模式运行时反模式两个维度切入,严格采用六步诊断法,根因分析显式关联前文第 2 篇(B+Tree 索引结构)、第 3 篇(MVCC 与 Undo Log)、第 4 篇(行锁与间隙锁加锁规则)、第 5 篇(SQL 优化器代价估算与执行计划)、第 6 篇(主从复制原理与 Binlog 格式)、第 9 篇(连接管理)等核心技术原理。模块 7 提供可打印的诊断工具速查表与现象→工具映射矩阵,模块 8 绘制覆盖"慢查询突增、锁等待激增、主从延迟、连接数耗尽"四大核心故障的多层级标准化排查决策树,模块 9 以 18 道面试故障排查题收束,与前 9 篇原理面试题形成完整的理论与实践校验闭环。

逐模块说明
  • 模块 1:索引反模式(2 设计 + 3 运行时) :涵盖冗余索引与重复索引、复合索引列顺序错误、隐式类型转换、LIKE 前缀通配、统计信息过时,结合 sys.schema_redundant_indexesEXPLAIN key_lenSHOW WARNINGS 等工具精准定位。
  • 模块 2:SQL 与查询反模式(2 设计 + 3 运行时) :剖析 SELECT * 导致回表与失去覆盖索引、ORDER BY RAND() 的灾难性排序、深度分页的性能退化、依赖子查询的多次执行以及 Join 驱动表选择错误,借助 EXPLAIN FORMAT=TREEEXPLAIN ANALYZE 揭示执行细节。
  • 模块 3:事务与锁反模式(1 设计 + 4 运行时) :从事务边界包含外部 I/O、长事务阻塞 Purge、无索引 UPDATE 全表加锁、交叉锁死锁、到 RR 隔离级别下快照读丢失更新,深度使用 SHOW ENGINE INNODB STATUSsys.innodb_lock_waitsperformance_schema.data_locks 进行锁分析。
  • 模块 4:复制与架构反模式(1 设计 + 2 运行时) :解决 STATEMENT 格式导致的非确定性函数不一致、主从延迟致读写分离读到旧数据,以及分片键数据倾斜,依托 pt-heartbeatpt-table-checksum 和 ShardingSphere 监控。
  • 模块 5:DDL 与表设计反模式(1 设计 + 2 运行时) :讨论外键级联锁危害、直接 ALTER TABLE 的元数据锁风暴、VARCHAR 过大导致行溢出,推荐 pt-online-schema-changegh-ost
  • 模块 6:连接与配置反模式(1 设计 + 3 运行时) :强调 max_connections 全局协调、maxLifetimewait_timeout 不等式、idleTimeoutSleep 连接堆积、connect_timeout 协调问题,与 JDBC 系列第 10 篇联动使用 Arthas 和连接池 Metrics。
  • 模块 7:诊断工具集与映射表:汇总 MySQL 端 7 种核心诊断工具和 JDBC 端 4 种工具,形成不少于 14 行的"现象→工具→命令"速查表,并绘制诊断工具全景图。
  • 模块 8:多层级标准化排查决策树:为四大核心故障分别绘制详细的决策流程图,每个节点包含具体的诊断命令和前文原理引用,确保故障发生时能够按图索骥、逻辑推演。
  • 模块 9:面试高频故障排查专题:18 道题目全部来源于线上真实故障场景,涵盖索引失效、锁问题、复制延迟、连接异常、慢查询、DDL 事故等,每题提供完整排查步骤、关键命令输出解读、根因分析和最佳实践,并附加一道综合系统设计题。
关键结论

MySQL 反模式的根因几乎无一例外都可以追溯到前 9 篇的核心原理。掌握六步诊断法、设计/运行时双视角分析范式、多层级标准化排查决策树,以及与 JDBC 系列联动的全链路排障能力,是将理论知识转化为实际排障战斗力的唯一途径。


1. 索引反模式

索引是数据库性能最关键的杠杆,也是反模式最为集中的领域。设计阶段的冗余、列顺序错误,运行时的隐式类型转换、通配符滥用、统计信息过时,均能使精心设计的索引完全失效。

1.1 设计反模式案例 1:冗余索引与重复索引

1.1.1 错误示例
复制代码

CREATE TABLE orders ( id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT NOT NULL, status TINYINT NOT NULL DEFAULT 0, create_time DATETIME NOT NULL, INDEX idx_user_id (user_id), -- 冗余 INDEX idx_user_status (user_id, status), -- 前导列与 idx_user_id 重复 INDEX idx_user_time (user_id, create_time) -- 前导列与 idx_user_id 重复 ) ENGINE=InnoDB;

1.1.2 现象描述
  • 磁盘空间异常增长information_schema.TABLESINDEX_LENGTH 显著高于预期,总索引体积是必要值的 2~3 倍。
  • 写入性能退化INSERT 语句的 p99 延迟从 2ms 上升至 15ms。performance_schema.table_io_waits_summary_by_index_usage 显示这三个索引的 COUNT_INSERT 完全相同,证明每次插入都要同时维护三棵 B+Tree。
  • 优化器偶发选错索引 :统计信息波动时,优化器可能选择 idx_user_time 而非覆盖更优的 idx_user_status,导致额外的回表和排序。
  • sys.schema_redundant_indexes 直接给出证据:
复制代码

SELECT * FROM sys.schema_redundant_indexes WHERE table_name = 'orders'\G -- redundant_index_name: idx_user_id -- dominant_index_name: idx_user_status -- sql_drop_index: ALTER TABLE order_db.orders DROP INDEX idx_user_id

1.1.3 排查思路
  1. 审查索引结构 :定期对核心表执行 SHOW INDEX FROM orders,关注具有相同前导列的索引组合。
  2. 量化索引维护成本 :查询 performance_schema.table_io_waits_summary_by_index_usage,对比各索引的 COUNT_INSERTCOUNT_UPDATECOUNT_DELETE,若多个索引的写入次数高度一致,则强关联冗余。
  3. 使用自动化工具 :将 pt-duplicate-key-checker 集成到 CI/CD 流程,或定期执行 sys.schema_redundant_indexes 生成报告。
  4. 评估查询覆盖度 :确认最宽的复合索引(如 idx_user_status(user_id, status))是否已经能够满足所有以 user_id 开头的查询需求。
1.1.4 根因分析

根因详见第 2 篇 B+Tree 索引结构与最左前缀原则 。InnoDB 中每个二级索引都是一棵独立的 B+Tree,叶子节点存储主键值。复合索引 idx_user_status(user_id, status) 的最左列 user_id 完全可以充当单列索引 idx_user_id(user_id) 的角色,任何等值查询、范围查询或排序只要以 user_id 开始,都能利用该复合索引。保留冗余索引意味着:

  • 写入放大 :每次 INSERT 都要分别在三个 B+Tree 上执行定位、插入、可能的页分裂操作,触发额外的 redo log 和 undo log。
  • 内存浪费:三个索引均竞争 InnoDB Buffer Pool 的宝贵空间,降低整体缓存命中率。
  • 优化器负担:更多的候选索引增加了查询优化阶段的分析成本。

源码层面,row_ins_sec_index_entry_low() 函数负责将记录插入每个二级索引,冗余索引的数量直接线性增加了该函数的调用次数。

1.1.5 修正方案
复制代码

-- 保留覆盖范围最广的复合索引,并增加 create_time 以满足排序需求 ALTER TABLE orders DROP INDEX idx_user_id, DROP INDEX idx_user_time, ADD INDEX idx_user_status_time (user_id, status, create_time);

执行后验证:

复制代码

EXPLAIN SELECT * FROM orders WHERE user_id = 100; -- key: idx_user_status_time, key_len: 8 (只用到了 user_id), type: ref EXPLAIN SELECT * FROM orders WHERE user_id = 100 AND status = 1; -- key: idx_user_status_time, key_len: 9, type: ref

1.1.6 最佳实践
  • 新建索引前强制审查 :使用 sys.schema_redundant_indexes 检查是否已有可覆盖的索引前缀。
  • 复合索引优先原则:当多个查询共用某个前导列时,倾向于创建一个宽复合索引而非多个单列索引。
  • 定期清理(月度) :在业务低峰期根据 sys.schema_unused_indexesschema_redundant_indexes 删除未使用或冗余的索引,但务必确保监控周期已覆盖所有业务场景。
  • CI/CD 自动化 :集成 pt-duplicate-key-checker 作为上线前的检查关卡。

1.2 设计反模式案例 2:复合索引列顺序错误

1.2.1 错误示例
复制代码

CREATE TABLE orders ( id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT NOT NULL, -- 区分度极高(800 万去重值) status TINYINT NOT NULL, -- 区分度极低(仅 5 种状态) create_time DATETIME NOT NULL, INDEX idx_status_user_time (status, user_id, create_time) -- 低区分度列在最左 ) ENGINE=InnoDB;

1.2.2 现象描述

典型查询 SELECT * FROM orders WHERE user_id = 12345 AND status = 2 ORDER BY create_time DESC LIMIT 20EXPLAIN 输出:

复制代码

+----+-------------+--------+------+-----------------------+-----------------------+---------+-------+--------+-----------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+------+-----------------------+-----------------------+---------+-------+--------+-----------------------------+ | 1 | SIMPLE | orders | ref | idx_status_user_time | idx_status_user_time | 1 | const | 450000 | Using index condition; Using filesort | +----+-------------+--------+------+-----------------------+-----------------------+---------+-------+--------+-----------------------------+

  • key_len=1 表示仅使用了索引的第一列 status(TINYINT 占 1 字节),user_id 列完全未发挥作用。
  • rows=450000 说明扫描了所有 status=2 的行,然后逐行过滤 user_id
  • Extra 包含 Using filesort,表明无法利用索引完成排序。
  • 实际执行时间从预期的 5ms 膨胀到 3.2 秒,CPU 和 IO 飙升。
1.2.3 排查思路
  1. 分析慢查询指纹pt-query-digest 识别出该查询消耗了 40% 的总响应时间。
  2. 计算列区分度
复制代码

SELECT COUNT(DISTINCT status) AS status_card, COUNT(DISTINCT user_id) AS user_id_card FROM orders; -- status_card=5, user_id_card=8000000

  1. 深入 EXPLAIN :使用 EXPLAIN FORMAT=JSON 查看 "key_length": 1,确认索引使用不充分。
  2. 对比索引调整前后 :在测试环境创建以 user_id 开头的索引,执行时间降至 15ms,key_len 变为 9,Extrafilesort
1.2.4 根因分析

根因详见第 2 篇 B+Tree 最左前缀原则与索引列顺序对查询性能的影响 。复合索引在 B+Tree 中首先按第一列排序,第一列相同再按第二列排序,以此类推。当最左列为低区分度的 status 时,索引能够被优化器选中(因为 status 是等值条件),但 status=2 对应的索引叶子节点范围极大(覆盖 450000 行),其内部的 user_idcreate_time 并未全局有序,只是在 status 分组内局部有序。因此:

  • 无法通过 user_id=12345 进行精确跳跃,只能扫描所有 status=2 的记录,然后再在 Server 层过滤。
  • ORDER BY create_time 无法利用索引顺序,因为索引在 status 组内的排序是 user_id 优先,而非 create_time 优先,所以必须进行 filesort

如果把 user_id 放在最左,索引就能够通过二分查找直接定位到 user_id=12345 的范围,然后在其中迅速筛选 status=2 并按 create_time 有序扫描。

1.2.5 修正方案
复制代码

ALTER TABLE orders DROP INDEX idx_status_user_time; ALTER TABLE orders ADD INDEX idx_user_status_time (user_id, status, create_time);

修正后 EXPLAINkey_len=9rows=20Extra=Using index condition,无排序。

1.2.6 最佳实践
  • 区分度决定左前缀:复合索引最左列必须是 WHERE 条件中出现频率高且区分度大的列。
  • 等值→范围→排序:索引列顺序应遵循"等值查询列 → 范围查询列 → 排序列"的原则。
  • 验证 key_lenkey_len 应当等于使用到的所有索引列的字节宽度之和,差值即暗示列未被有效利用。
  • 定期使用 pt-index-usage 分析慢查询日志,发现低效索引。

1.3 运行时反模式案例 1:隐式类型转换导致索引失效

1.3.1 错误示例
复制代码

// MyBatis Mapper 方法,参数为 Long @Select("SELECT * FROM users WHERE mobile = #{mobile}") User findByMobile(@Param("mobile") Long mobile);

数据库表结构:mobile VARCHAR(11) NOT NULL, INDEX idx_mobile(mobile)。 实际执行 SQL:SELECT * FROM users WHERE mobile = 13800138000;(参数未加引号)。

1.3.2 现象描述
  • EXPLAIN 输出:
复制代码

+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+ | 1 | SIMPLE | users | ALL | idx_mobile | NULL | NULL | NULL | 5000000 | Using where | +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+

type=ALL 全表扫描,key=NULL 索引完全未使用,rows=5000000

  • SHOW WARNINGS 显示优化器重写后的语句:SELECT * FROM users WHERE CAST(mobile AS SIGNED) = 13800138000,证明发生了隐式类型转换。
  • 查询响应时间从 5ms 暴增至 2.8s,数据库 CPU 使用率从 30% 升至 90%。
1.3.3 排查思路
  1. 对比测试 :在数据库直接执行 WHERE mobile = '13800138000'(带引号)与 WHERE mobile = 13800138000(不带引号),执行时间差异悬殊。
  2. 抓取隐式转换证据 :对可疑 SQL 执行 EXPLAIN 后立即 SHOW WARNINGS,查看是否出现 CASTCONVERT 等函数。
  3. 追溯应用代码 :通过 Arthas 或日志确认传入参数的实际 Java 类型,找到 LongVARCHAR 的类型失配。
  4. 使用 optimizer_trace
复制代码

SET optimizer_trace='enabled=on'; SELECT * FROM users WHERE mobile = 13800138000; SELECT * FROM information_schema.OPTIMIZER_TRACE\G

在输出的 "considered_execution_plans" 中,会看到优化器评估 range 访问路径时明确提到需要 cast 函数,因此放弃索引。

1.3.4 根因分析

根因详见第 2 篇 B+Tree 索引结构、第 5 篇优化器索引选择规则与类型转换逻辑 。MySQL 在处理字符串列与数值的比较时,会依据一套类型转换规则,将字符串列的值逐行转换为数值(等价于 CAST(mobile AS SIGNED))再进行比较。由于索引存储的是原始字符串,一旦在索引列上施加函数,B+Tree 的有序性便无法直接用于范围定位或二分查找。在源码 sql/sql_optimizer.ccref_accessfind_best_ref 函数中,优化器检查 WHERE 条件是否能够直接映射到索引键值,若发现隐式转换,则判定为不可进行 refrange 访问,只能退化为全表扫描。

1.3.5 修正方案

方案一(推荐) :修改 Java 代码,将 mobile 字段类型改为 String,确保 PreparedStatement 设置参数时类型匹配。

复制代码

@Select("SELECT * FROM users WHERE mobile = #{mobile}") User findByMobile(@Param("mobile") String mobile);

方案二:如果短期内无法修改应用代码,可创建虚拟列索引作为过渡:

复制代码

ALTER TABLE users ADD COLUMN mobile_int BIGINT GENERATED ALWAYS AS (CAST(mobile AS SIGNED)) STORED; ALTER TABLE users ADD INDEX idx_mobile_int (mobile_int);

方案三:在 SQL 中显式转换参数,避免在列上使用函数:

复制代码

SELECT * FROM users WHERE mobile = CAST(13800138000 AS CHAR);

1.3.6 最佳实践
  • 类型一致性原则:数据库列类型与应用层字段类型必须严格一致,纳入 Code Review 检查清单。
  • 告警配置 :设置 log_warnings=2,MySQL 会将隐式类型转换告警写入错误日志,便于事后审计。
  • 监控慢查询 :对 type=ALLkey=NULL 的查询设置阈值告警,及时介入排查。
  • 测试覆盖:在测试环境中模拟生产数据类型,确保所有 SQL 均能使用预期索引。

1.4 运行时反模式案例 2:LIKE '%xxx' 前缀通配导致索引失效

1.4.1 错误示例
复制代码

SELECT * FROM products WHERE product_name LIKE '%手机%';

1.4.2 现象描述
  • EXPLAIN 输出:type=ALL, rows=500000, Extra=Using where
  • 每次搜索触发全表扫描,并发搜索稍高便导致 CPU 100%,大量 Sending data 状态堆积。
  • SHOW STATUS LIKE 'Handler_read%'Handler_read_rnd_next 数值急剧增长,表明大规模全表扫描正在进行。
1.4.3 排查思路
  1. 确认慢查询指纹pt-query-digest 显示 LIKE '%手机%' 类型的查询占总响应时间的 60% 以上。
  2. EXPLAIN 验证 :与 LIKE '手机%' 对比,后者 type=range 使用索引,前者 type=ALL
  3. 检查索引结构 :确认 product_name 上虽然有普通索引,但无法用于前缀通配的场景。
  4. 业务评估:与产品确认是否必须支持任意位置的模糊匹配,是否可以考虑搜索引擎方案。
1.4.4 根因分析

根因详见第 2 篇 B+Tree 有序存储与范围扫描机制 。B+Tree 的叶子节点按照索引列的字典序排序,优化器可以将 LIKE '手机%' 转换为 product_name >= '手机' AND product_name < '手环' 的范围扫描,精确界定扫描起止位置。而 '%手机%' 的通配符在开头,无法确定扫描的起始键值,优化器无法将其转化为范围条件,只能选择全表扫描逐行执行模式匹配。源码 sql/sql_optimizer.cc 中的 check_quick_select() 函数会判断 LIKE 模式是否可转化为 range,遇到前导通配符直接返回失败。

1.4.5 修正方案

方案一:全文索引(适合中等规模的文本搜索):

复制代码

ALTER TABLE products ADD FULLTEXT INDEX ft_product_name (product_name); SELECT * FROM products WHERE MATCH(product_name) AGAINST('手机' IN NATURAL LANGUAGE MODE) LIMIT 20;

方案二:Elasticsearch 等搜索引擎(推荐高并发、大数据量场景):通过 Canal 或 DataX 将数据实时同步至 ES,将全文搜索流量转移至 ES。

方案三:引导业务改造 :如果业务可以接受,将搜索改为后缀匹配 LIKE '手机%',或使用分类筛选缩小扫描范围。

方案四:逆向函数索引(适合后缀匹配,如邮箱域名):

复制代码

ALTER TABLE products ADD COLUMN reversed_name VARCHAR(200) GENERATED ALWAYS AS (REVERSE(product_name)) STORED; ALTER TABLE products ADD INDEX idx_reversed (reversed_name); SELECT * FROM products WHERE REVERSE(product_name) LIKE REVERSE('%@example.com');

1.4.6 最佳实践
  • 设计阶段评估搜索需求 :若频繁需要全模糊搜索,应一开始就引入全文索引或 ES,避免使用 LIKE '%xxx%' 作为主力搜索方式。
  • 监控全表扫描 :通过 sys.schema_tables_with_full_table_scans 定期审查全表扫描语句。
  • 索引前缀长度优化:若必须使用后缀匹配,注意前缀索引长度需平衡区分度与空间。
相关推荐
STARFALL0011 小时前
MySQL 运维
运维·数据库·mysql
XD7429716361 小时前
科技早报晚报|2026年5月14日:数据库沙箱、文档解析与 GPU 共享,今天更值得做成产品的 3 个技术机会
数据库·科技·开源项目·开发者工具·ai基础设施
祀爱1 小时前
ASP.NET Core 集成NLog详细教程
数据库·后端·asp.net
醇氧1 小时前
CentOS 7 安装 MySQL 8.0.28 el7 (完美兼容 OpenSSL 1.1)
linux·mysql·centos
java修仙传1 小时前
Java 实习日记:一次 Excel 导入校验 Bug 的定位与数据更新逻辑优化
java·数据库·bug·excel·后端开发
wa的一声哭了1 小时前
Mit6.s081 Interrupts and device driver(中断和设备驱动)
linux·服务器·arm开发·数据库·python·gpt·算法
码界筑梦坊1 小时前
117-基于Python的印度犯罪数据可视化分析系统
开发语言·python·mysql·信息可视化·毕业设计·echarts·fastapi
RoboWizard1 小时前
DIY移动硬盘?2230能否堪大任!
数据库·人工智能·智能手机·性能优化·负载均衡
六月雨滴1 小时前
CDB/PDB 多租户存储架构(12c+)
数据库·oracle·dba