• [问题求助] 我写了一条SQL查询,在测试环境10万条数据时运行很快,但到生产环境100万数据就慢得要命,已经给查询字段加了索引,用EXPLAIN看执行计划显示是Seq Scan而不是Index Scan,这是为什么?
    我写了一条SQL查询,在测试环境10万条数据时运行很快,但到生产环境100万数据就慢得要命,已经给查询字段加了索引,用EXPLAIN看执行计划显示是Seq Scan而不是Index Scan,这是为什么?
  • [交流吐槽] 【话题交流】你愿意把数据库权限交给AI吗?MCP权限自动化探索
    权限管理一向是数据库安全的核心。但在AI+MCP方案中,权限分配/审核可以由AI模型辅助完成,比如根据操作行为分析动态调整权限。你怎么看这种方式?它是提高效率的利器,还是埋下风险的雷?欢迎讨论。
  • [问题求助] 我们的PostgreSQL数据库每天晚上12点都会变得特别慢,查看日志发现有个叫autovacuum的进程在运行,这个进程是干什么的?可以直接关掉吗?还是说需要调整它的运行时间?
    我们的PostgreSQL数据库每天晚上12点都会变得特别慢,查看日志发现有个叫autovacuum的进程在运行,这个进程是干什么的?可以直接关掉吗?还是说需要调整它的运行时间?
  • [问题求助] 我在Docker里部署了PostgreSQL容器,但重启容器后发现数据全部丢失了,明明创建容器的时候指定了数据卷,这是哪里配置错了?Docker环境下使用PostgreSQL需要注意什么?
    我在Docker里部署了PostgreSQL容器,但重启容器后发现数据全部丢失了,明明创建容器的时候指定了数据卷,这是哪里配置错了?Docker环境下使用PostgreSQL需要注意什么?
  • [问题求助] 公司新项目要用PostgreSQL,领导让我评估下需要什么样配置的服务器,预计数据量在500GB左右,日均访问量10万次,请问应该如何估算CPU、内存、磁盘的配置?SSD和机械硬盘差别大吗?
    公司新项目要用PostgreSQL,领导让我评估下需要什么样配置的服务器,预计数据量在500GB左右,日均访问量10万次,请问应该如何估算CPU、内存、磁盘的配置?SSD和机械硬盘差别大吗?
  • [问题求助] 我按照官方文档配置了postgresql.conf文件,把shared_buffers改成了4GB,结果PostgreSQL启动失败,日志显示"could not create shared memory segment",这是什么原因?
    我按照官方文档配置了postgresql.conf文件,把shared_buffers改成了4GB,结果PostgreSQL启动失败,日志显示"could not create shared memory segment",这是什么原因?Linux系统是不是还需要调整什么参数?
  • [问题求助] 线上PostgreSQL数据库运行了半年后,突然收到告警说磁盘快满了,但我看表数据其实没增加多少,后来发现是pg_wal目录占了好几十个G,这些WAL文件能直接删除吗?怎么控制WAL的大小?
    线上PostgreSQL数据库运行了半年后,突然收到告警说磁盘快满了,但我看表数据其实没增加多少,后来发现是pg_wal目录占了好几十个G,这些WAL文件能直接删除吗?怎么控制WAL的大小?
  • [技术干货] InnoDB数据页详解
    问题描述InnoDB数据页是什么?数据页的结构是怎样的?数据页如何存储记录?如何优化数据页的使用?核心答案InnoDB数据页的四大特性:固定大小:默认16KB物理连续:保证数据连续性逻辑有序:通过双向链表连接动态调整:支持页分裂和合并详细分析1. 数据页结构基本结构:-- 查看页大小 SHOW VARIABLES LIKE 'innodb_page_size'; -- 查看表空间信息 SHOW TABLESPACE STATUS; File Header:文件头,38字节Page Header:页头,56字节Infimum + Supremum:虚拟记录,26字节User Records:用户记录,动态大小Free Space:空闲空间,动态大小Page Directory:页目录,动态大小File Trailer:文件尾,8字节记录存储:-- 查看记录格式 SHOW TABLE STATUS LIKE 'users'; -- 查看索引信息 SHOW INDEX FROM users; 变长字段长度列表NULL值标志位记录头信息列数据2. 页管理机制页分裂:-- 查看页分裂统计 SHOW ENGINE INNODB STATUS; -- 查看索引碎片 SELECT * FROM information_schema.INNODB_SYS_TABLESPACES; 触发条件:空间不足分裂过程:复制记录分裂影响:性能下降页合并:-- 查看页合并统计 SHOW ENGINE INNODB STATUS; -- 优化表空间 OPTIMIZE TABLE users; 触发条件:空间浪费合并过程:移动记录合并影响:空间回收3. 页优化策略填充因子:-- 设置填充因子 ALTER TABLE users ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=8; -- 查看填充因子 SHOW TABLE STATUS LIKE 'users'; 控制页填充率减少页分裂提高空间利用率记录格式:-- 设置记录格式 ALTER TABLE users ROW_FORMAT=DYNAMIC; -- 查看记录格式 SHOW TABLE STATUS LIKE 'users'; COMPACT:紧凑格式DYNAMIC:动态格式COMPRESSED:压缩格式优化建议页大小优化:-- 设置页大小 SET GLOBAL innodb_page_size = 16384; -- 查看页大小 SHOW VARIABLES LIKE 'innodb_page_size'; 默认16KB根据数据特点调整考虑硬件特性记录格式优化:-- 使用动态格式 ALTER TABLE users ROW_FORMAT=DYNAMIC; -- 使用压缩格式 ALTER TABLE users ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; 选择合适格式控制记录大小优化存储效率常见面试题基础问题:Q1:什么是InnoDB数据页?它的作用是什么?A1:InnoDB数据页是InnoDB存储引擎的基本存储单位,默认大小为16KB。它用于存储表数据、索引数据和其他元数据,是InnoDB实现事务、MVCC和索引的基础。Q2:InnoDB数据页的结构是怎样的?A2:InnoDB数据页的结构包括:1) 文件头(File Header);2) 页头(Page Header);3) 行记录(Records);4) 空闲空间(Free Space);5) 页目录(Page Directory);6) 文件尾(File Trailer)。每个部分都有特定的作用。Q3:InnoDB数据页的大小可以调整吗?如何调整?A3:InnoDB数据页的大小可以通过innodb_page_size参数调整,可选值为4KB、8KB、16KB、32KB和64KB。调整需要在创建数据库实例时进行,一旦设置就不能更改。进阶问题:Q1:InnoDB数据页是如何管理记录的?A1:InnoDB数据页通过以下方式管理记录:1) 使用页目录进行记录定位;2) 通过记录头信息管理记录状态;3) 使用空闲空间管理记录插入;4) 通过记录格式存储不同类型的数据;5) 使用溢出页处理大字段;6) 通过页分裂处理空间不足。Q2:InnoDB数据页的分裂和合并是如何进行的?A2:页分裂和合并的过程:1) 当页空间不足时触发分裂;2) 将部分记录移动到新页;3) 更新页目录和指针;4) 当页空间利用率过低时触发合并;5) 将相邻页的记录合并;6) 更新相关页的指针和目录。Q3:InnoDB数据页的填充因子是什么?如何设置?A3:填充因子是指页中已使用空间的比例。可以通过innodb_fill_factor参数设置,默认值为100。设置合适的填充因子可以平衡空间利用率和性能,通常建议设置为80-90。实战问题:Q1:如何优化InnoDB数据页的使用?A1:优化InnoDB数据页使用的方法:1) 选择合适的页大小;2) 设置合理的填充因子;3) 优化表结构设计;4) 合理使用索引;5) 控制记录大小;6) 定期维护表空间。需要根据具体场景选择合适的优化方法。Q2:如何处理大字段的存储?A2:处理大字段存储的方法:1) 使用溢出页存储;2) 考虑使用TEXT/BLOB类型;3) 控制字段大小;4) 使用压缩功能;5) 考虑外部存储;6) 优化查询方式。需要根据数据特点选择合适的存储方案。Q3:如何监控InnoDB数据页的使用情况?A3:监控InnoDB数据页使用的方法:1) 使用SHOW TABLE STATUS;2) 查看INFORMATION_SCHEMA表;3) 使用性能监控工具;4) 分析慢查询日志;5) 检查系统表空间;6) 监控页分裂和合并情况。需要定期进行监控和分析。实际案例分析大表优化:-- 优化前 CREATE TABLE users ( id BIGINT PRIMARY KEY, name VARCHAR(255), content TEXT ) ROW_FORMAT=COMPACT; -- 优化后 CREATE TABLE users ( id BIGINT PRIMARY KEY, name VARCHAR(255), content TEXT ) ROW_FORMAT=DYNAMIC; 使用动态格式优化存储结构提高查询效率高并发优化:-- 优化前 CREATE TABLE orders ( id BIGINT PRIMARY KEY, user_id BIGINT, amount DECIMAL(10,2) ) ROW_FORMAT=COMPACT; -- 优化后 CREATE TABLE orders ( id BIGINT PRIMARY KEY, user_id BIGINT, amount DECIMAL(10,2) ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; 使用压缩格式减少IO操作提高并发性能面试要点基础概念:数据页的定义页结构组成记录存储方式性能优化:页分裂优化空间利用率查询性能实战经验:大表优化高并发处理空间管理总结InnoDB数据页的核心特性:固定大小:16KB物理连续:保证数据连续性逻辑有序:通过双向链表连接动态调整:支持页分裂和合并在实际应用中,应该根据数据特点和业务需求,选择合适的页大小和记录格式,以提高存储效率和查询性能。
  • [技术干货] 慢SQL问题排查
    问题描述如何发现慢SQL?如何分析慢SQL的原因?如何优化慢SQL?如何预防慢SQL?核心答案慢SQL排查的四大步骤:慢查询日志分析执行计划解读性能指标监控优化方案实施详细分析1. 慢查询日志分析开启慢查询日志:-- 查看慢查询日志配置 SHOW VARIABLES LIKE 'slow_query%'; SHOW VARIABLES LIKE 'long_query_time'; -- 开启慢查询日志 SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 1; SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log'; slow_query_log:是否开启慢查询日志long_query_time:慢查询阈值slow_query_log_file:日志文件路径分析慢查询日志:-- 使用mysqldumpslow分析 mysqldumpslow -s t /var/log/mysql/slow.log -- 使用pt-query-digest分析 pt-query-digest /var/log/mysql/slow.log查询执行时间查询频率查询模式2. 执行计划解读EXPLAIN分析:-- 基本用法 EXPLAIN SELECT * FROM users WHERE name = 'John'; -- 分析结果 +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | users | ALL | NULL | NULL | NULL | NULL | 1000 | Using where | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ type为ALL表示全表扫描key为NULL表示未使用索引rows表示扫描行数性能问题定位:-- 查看表状态 SHOW TABLE STATUS LIKE 'users'; -- 查看索引使用情况 SHOW INDEX FROM users; -- 查看表结构 SHOW CREATE TABLE users; 表数据量索引使用情况表结构设计3. 性能指标监控系统指标:-- 查看系统状态 SHOW GLOBAL STATUS; -- 查看系统变量 SHOW GLOBAL VARIABLES; -- 查看进程列表 SHOW PROCESSLIST; CPU使用率内存使用情况磁盘IO网络流量数据库指标:-- 查看连接数 SHOW STATUS LIKE 'Threads_connected'; -- 查看缓存命中率 SHOW STATUS LIKE 'Qcache%'; -- 查看InnoDB状态 SHOW ENGINE INNODB STATUS; 连接数量缓存命中率锁等待事务状态4. 优化方案实施索引优化:-- 创建合适的索引 CREATE INDEX idx_name_age ON users(name, age); -- 使用覆盖索引 SELECT name, age FROM users WHERE name = 'John'; -- 避免冗余索引 DROP INDEX idx_name ON users; 遵循最左前缀原则使用覆盖索引避免冗余索引查询优化:-- 优化查询顺序 SELECT * FROM users WHERE status = 1 AND name = 'John' AND age > 20; -- 使用索引提示 SELECT * FROM users FORCE INDEX(idx_name) WHERE name = 'John'; -- 优化子查询 SELECT u.* FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.amount > 1000); 调整查询顺序使用索引提示优化子查询优化建议索引优化:-- 创建复合索引 CREATE INDEX idx_name_age_status ON users(name, age, status); -- 使用覆盖索引 SELECT name, age FROM users WHERE name = 'John'; -- 避免冗余索引 DROP INDEX idx_name ON users; 遵循最左前缀原则使用覆盖索引避免冗余索引查询优化:-- 优化查询顺序 SELECT * FROM users WHERE status = 1 AND name = 'John' AND age > 20; -- 使用索引提示 SELECT * FROM users FORCE INDEX(idx_name) WHERE name = 'John'; -- 优化子查询 SELECT u.* FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.amount > 1000); 调整查询顺序使用索引提示优化子查询常见面试题基础问题:Q1:什么是慢SQL?如何定义慢SQL?A1:慢SQL是指执行时间超过预设阈值的SQL语句。通常通过设置long_query_time参数来定义,默认值为10秒。可以通过慢查询日志来记录和分析这些SQL语句。Q2:慢SQL会带来哪些问题?A2:慢SQL会导致:1) 系统响应变慢;2) 资源占用增加;3) 并发处理能力下降;4) 用户体验变差;5) 可能引发系统故障;6) 影响业务正常运行。Q3:如何发现慢SQL?A3:可以通过以下方式发现慢SQL:1) 开启慢查询日志;2) 使用性能监控工具;3) 分析执行计划;4) 查看系统资源使用情况;5) 收集用户反馈;6) 定期性能检查。进阶问题:Q1:如何分析慢SQL的执行计划?A1:分析执行计划的步骤:1) 使用EXPLAIN查看执行计划;2) 分析type字段判断访问方式;3) 检查possible_keys和key字段;4) 查看rows字段评估扫描行数;5) 分析Extra字段获取额外信息;6) 根据分析结果制定优化方案。Q2:慢SQL优化的主要方法有哪些?A2:慢SQL优化的主要方法:1) 优化查询语句;2) 调整索引结构;3) 优化表结构;4) 调整数据库参数;5) 使用缓存;6) 考虑分表分库。需要根据具体情况选择合适的优化方法。Q3:如何预防慢SQL问题?A3:预防慢SQL的方法:1) 规范SQL编写;2) 合理设计索引;3) 定期性能检查;4) 建立监控机制;5) 制定应急预案;6) 进行性能测试。需要从多个方面进行预防。实战问题:Q1:如何处理高并发场景下的慢SQL问题?A1:处理高并发场景下的慢SQL:1) 优化查询减少锁竞争;2) 使用缓存减轻数据库压力;3) 考虑读写分离;4) 优化事务处理;5) 调整连接池配置;6) 监控系统性能。需要综合考虑各种因素。Q2:如何优化大数据量下的慢SQL?A2:优化大数据量下的慢SQL:1) 使用分区表;2) 优化索引结构;3) 控制返回数据量;4) 使用分页查询;5) 考虑分表分库;6) 使用缓存。需要根据数据特点选择合适的优化方案。Q3:如何评估慢SQL优化的效果?A3:评估优化效果的方法:1) 对比优化前后的执行计划;2) 监控查询响应时间;3) 分析系统资源使用情况;4) 观察并发处理能力;5) 检查业务指标变化;6) 收集用户反馈。需要从多个维度综合评估。实际案例分析电商订单查询:-- 优化前 SELECT * FROM orders WHERE YEAR(create_time) = 2023 AND status = 1 ORDER BY amount DESC LIMIT 10; -- 优化后 SELECT * FROM orders WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01' AND status = 1 ORDER BY amount DESC LIMIT 10; 避免使用日期函数使用范围查询优化排序字段用户搜索功能:-- 优化前 SELECT * FROM users WHERE name LIKE '%John%' OR email LIKE '%john%'; -- 优化后 SELECT * FROM users WHERE name LIKE 'John%' UNION SELECT * FROM users WHERE email LIKE 'john%'; 避免使用全模糊使用右模糊优化查询方式面试要点基础概念:慢SQL的定义慢查询日志执行计划分析性能优化:索引优化技巧查询优化方法参数调优策略实战经验:问题排查流程优化案例分析最佳实践总结总结慢SQL排查的主要步骤:慢查询日志分析执行计划解读性能指标监控优化方案实施在实际应用中,应该根据具体情况选择合适的排查方法,以提高查询性能。
  • [技术干货] SQL调优详解
    问题描述如何分析SQL性能问题?如何优化慢查询?如何选择合适的索引?如何调整数据库参数?核心答案SQL调优的四大方向:执行计划分析索引优化查询优化参数调优详细分析1. 执行计划分析EXPLAIN详解:-- 基本用法 EXPLAIN SELECT * FROM users WHERE name = 'John'; -- 分析结果 +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | users | ref | idx_name | idx_name | 32 | const| 1 | Using where | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ id:查询的执行顺序select_type:查询的类型type:访问的方式possible_keys:可能使用的索引key:实际使用的索引rows:预计扫描行数Extra:额外的信息性能指标分析:-- 查看慢查询日志 SHOW VARIABLES LIKE 'slow_query_log'; SHOW VARIABLES LIKE 'long_query_time'; -- 分析慢查询 mysqldumpslow -s t /var/log/mysql/slow.log查询执行时间扫描行数返回行数临时表使用2. 索引优化索引设计原则:-- 创建合适的索引 CREATE INDEX idx_name_age ON users(name, age); -- 使用覆盖索引 SELECT name, age FROM users WHERE name = 'John'; -- 避免冗余索引 DROP INDEX idx_name ON users; 遵循最左前缀原则使用覆盖索引避免冗余索引考虑索引选择性索引使用技巧:-- 使用索引提示 SELECT * FROM users FORCE INDEX(idx_name) WHERE name = 'John'; -- 使用索引合并 SELECT * FROM users WHERE name = 'John' OR age = 25; -- 使用索引排序 SELECT * FROM users WHERE name = 'John' ORDER BY age; 使用索引提示使用索引合并使用索引排序3. 查询优化查询重写:-- 优化前 SELECT * FROM users WHERE YEAR(create_time) = 2023; -- 优化后 SELECT * FROM users WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01'; -- 优化前 SELECT * FROM users WHERE name LIKE '%John%'; -- 优化后 SELECT * FROM users WHERE name LIKE 'John%'; 避免使用函数避免使用模糊查询使用范围查询子查询优化:-- 优化前 SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE amount > 1000); -- 优化后 SELECT DISTINCT u.* FROM users u JOIN orders o ON u.id = o.user_id WHERE o.amount > 1000; -- 使用EXISTS优化 SELECT * FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.amount > 1000); 使用JOIN替代子查询使用EXISTS优化使用临时表优化4. 参数调优内存参数:-- 调整排序缓冲区 SET GLOBAL sort_buffer_size = 4M; -- 调整连接缓冲区 SET GLOBAL join_buffer_size = 4M; -- 调整临时表大小 SET GLOBAL tmp_table_size = 64M; sort_buffer_size:排序缓冲区join_buffer_size:连接缓冲区tmp_table_size:临时表大小缓存参数:-- 调整查询缓存 SET GLOBAL query_cache_size = 64M; -- 调整InnoDB缓冲池 SET GLOBAL innodb_buffer_pool_size = 1G; -- 调整键缓冲区 SET GLOBAL key_buffer_size = 256M; query_cache_size:查询缓存innodb_buffer_pool_size:缓冲池key_buffer_size:键缓冲区优化建议索引优化:-- 创建复合索引 CREATE INDEX idx_name_age_status ON users(name, age, status); -- 使用覆盖索引 SELECT name, age FROM users WHERE name = 'John'; -- 避免冗余索引 DROP INDEX idx_name ON users; 遵循最左前缀原则使用覆盖索引避免冗余索引查询优化:-- 优化查询顺序 SELECT * FROM users WHERE status = 1 AND name = 'John' AND age > 20; -- 使用索引提示 SELECT * FROM users FORCE INDEX(idx_name) WHERE name = 'John'; -- 优化子查询 SELECT u.* FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.amount > 1000); 调整查询顺序使用索引提示优化子查询常见面试题基础问题:Q1:什么是SQL调优?为什么要进行SQL调优?A1:SQL调优是通过优化SQL语句、索引设计、执行计划等手段提高数据库查询性能的过程。进行SQL调优可以提升系统响应速度、减少资源消耗、提高并发处理能力,是数据库性能优化的重要手段。Q2:SQL调优的主要方法有哪些?A2:SQL调优的主要方法包括:优化查询语句、合理设计索引、分析执行计划、调整数据库参数、优化表结构、使用缓存等。需要根据具体场景选择合适的优化方法。Q3:如何判断SQL语句是否需要调优?A3:可以通过以下方式判断:查看执行计划是否合理、监控查询响应时间、分析慢查询日志、检查资源使用情况、观察系统负载等。当发现性能问题时,就需要进行SQL调优。进阶问题:Q1:执行计划分析在SQL调优中的作用是什么?A1:执行计划分析可以帮助我们了解SQL语句的执行过程,包括表的访问方式、索引使用情况、连接方式、排序方式等。通过分析执行计划,可以找出性能瓶颈,指导优化方向。Q2:索引优化需要注意哪些问题?A2:索引优化需要注意:遵循最左前缀原则、避免冗余索引、选择合适的索引类型、考虑索引维护成本、注意索引对写入性能的影响、定期维护索引统计信息等。Q3:如何优化大表查询性能?A3:优化大表查询性能的方法包括:使用分区表、合理设计索引、优化查询语句、使用覆盖索引、控制返回数据量、使用缓存、考虑分表分库等。需要根据具体场景选择合适的优化方案。实战问题:Q1:如何优化一个慢查询?A1:优化慢查询的步骤:1) 使用EXPLAIN分析执行计划;2) 检查索引使用情况;3) 优化查询语句;4) 调整索引结构;5) 考虑使用缓存;6) 验证优化效果。需要根据具体情况选择合适的优化方法。Q2:如何处理高并发场景下的SQL性能问题?A2:处理高并发场景下的SQL性能问题:1) 优化查询语句减少锁竞争;2) 合理设计索引提高查询效率;3) 使用缓存减少数据库压力;4) 考虑读写分离;5) 优化事务处理;6) 监控系统性能及时调整。Q3:如何评估SQL调优的效果?A3:评估SQL调优效果的方法:1) 对比优化前后的执行计划;2) 监控查询响应时间;3) 分析系统资源使用情况;4) 观察并发处理能力;5) 检查业务指标变化;6) 收集用户反馈。需要从多个维度综合评估优化效果。实际案例分析电商订单查询:-- 优化前 SELECT * FROM orders WHERE YEAR(create_time) = 2023 AND status = 1 ORDER BY amount DESC LIMIT 10; -- 优化后 SELECT * FROM orders WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01' AND status = 1 ORDER BY amount DESC LIMIT 10; 避免使用日期函数使用范围查询优化排序字段用户搜索功能:-- 优化前 SELECT * FROM users WHERE name LIKE '%John%' OR email LIKE '%john%'; -- 优化后 SELECT * FROM users WHERE name LIKE 'John%' UNION SELECT * FROM users WHERE email LIKE 'john%'; 避免使用全模糊使用右模糊优化查询方式面试要点基础概念:SQL调优的定义执行计划分析索引优化原则性能优化:查询优化技巧参数调优方法性能监控工具实战经验:常见问题处理优化案例分析最佳实践总结总结SQL调优的主要方向:执行计划分析索引优化查询优化参数调优在实际应用中,应该根据具体情况选择合适的优化方法,以提高查询性能。
  • [技术干货] 索引失效详解
    问题描述什么是索引失效?为什么会发生索引失效?索引失效会带来哪些问题?如何避免和处理索引失效?索引失效的优化策略有哪些?核心答案索引失效的六大核心原因:最左前缀原则失效:不满足最左前缀匹配函数和运算导致失效:对索引列使用函数或运算范围查询导致失效:使用范围查询条件模糊查询导致失效:使用通配符开头的模糊查询排序和分组导致失效:排序或分组字段顺序不当联合查询导致失效:多表连接条件不当详细分析1. 最左前缀原则失效原则分析:-- 创建联合索引 CREATE INDEX idx_name_age ON users(name, age); -- 有效查询 SELECT * FROM users WHERE name = 'John'; SELECT * FROM users WHERE name = 'John' AND age = 25; -- 失效查询 SELECT * FROM users WHERE age = 25; 索引顺序:必须按照索引定义的顺序使用部分使用:可以使用索引的前导列跳过列:不能跳过索引中的列优化建议:-- 优化前 SELECT * FROM users WHERE age = 25; -- 优化后 SELECT * FROM users WHERE name = 'John' AND age = 25; -- 或创建新索引 CREATE INDEX idx_age ON users(age); 调整查询:使用索引的前导列创建索引:根据查询需求创建合适索引索引顺序:合理设计索引列顺序2. 函数和运算导致失效失效场景:-- 创建索引 CREATE INDEX idx_created_at ON orders(created_at); -- 失效查询 SELECT * FROM orders WHERE DATE(created_at) = '2023-01-01'; SELECT * FROM orders WHERE amount + 100 > 1000; -- 有效查询 SELECT * FROM orders WHERE created_at >= '2023-01-01' AND created_at < '2023-01-02'; 函数使用:对索引列使用函数运算操作:对索引列进行运算类型转换:隐式类型转换优化建议:-- 优化前 SELECT * FROM orders WHERE DATE(created_at) = '2023-01-01'; -- 优化后 SELECT * FROM orders WHERE created_at >= '2023-01-01' AND created_at < '2023-01-02'; -- 或使用函数索引 CREATE INDEX idx_date_created ON orders((DATE(created_at))); 避免函数:直接使用索引列使用范围:使用范围查询替代函数函数索引:创建函数索引3. 范围查询导致失效失效分析:-- 创建索引 CREATE INDEX idx_age_salary ON employees(age, salary); -- 失效查询 SELECT * FROM employees WHERE age > 30 AND salary > 5000; -- 有效查询 SELECT * FROM employees WHERE age = 35 AND salary > 5000; 范围条件:使用范围查询条件多列索引:范围查询后的列失效优化器选择:可能选择不使用索引优化建议:-- 优化前 SELECT * FROM employees WHERE age > 30 AND salary > 5000; -- 优化后 SELECT * FROM employees WHERE age = 35 AND salary > 5000; -- 或使用覆盖索引 CREATE INDEX idx_age_salary_cover ON employees(age, salary, name); 精确匹配:使用精确匹配条件覆盖索引:创建覆盖索引索引顺序:调整索引列顺序4. 模糊查询导致失效失效场景:-- 创建索引 CREATE INDEX idx_name ON users(name); -- 失效查询 SELECT * FROM users WHERE name LIKE '%John%'; SELECT * FROM users WHERE name LIKE '%John'; -- 有效查询 SELECT * FROM users WHERE name LIKE 'John%'; 通配符开头:使用%开头的模糊查询全模糊查询:前后都使用通配符索引扫描:导致全表扫描优化建议:-- 优化前 SELECT * FROM users WHERE name LIKE '%John%'; -- 优化后 SELECT * FROM users WHERE name LIKE 'John%'; -- 或使用全文索引 CREATE FULLTEXT INDEX idx_name_ft ON users(name); 避免通配符:避免使用%开头使用前缀:使用前缀匹配全文索引:使用全文索引常见面试题基础问题:Q1:什么是索引失效?为什么会发生索引失效?A1:索引失效是指查询无法使用索引进行数据检索,导致全表扫描。主要原因包括不满足最左前缀原则、对索引列使用函数或运算、使用范围查询、使用通配符开头的模糊查询、排序分组字段顺序不当、联合查询条件不当等。Q2:索引失效会带来哪些问题?A2:索引失效会导致查询性能下降、系统资源消耗增加、响应时间变长、并发处理能力降低,严重时可能影响整个系统的稳定性。Q3:如何避免索引失效?A3:可以通过遵循最左前缀原则、避免对索引列使用函数和运算、合理使用范围查询、优化模糊查询、正确使用排序和分组、优化联合查询等方式避免索引失效。进阶问题:Q1:最左前缀原则是什么?为什么重要?A1:最左前缀原则是指在使用联合索引时,必须按照索引定义的顺序使用,不能跳过前面的列。这个原则重要是因为它决定了索引的使用效率,违反原则会导致索引失效。Q2:如何处理范围查询导致的索引失效?A2:可以通过使用精确匹配替代范围查询、创建覆盖索引、调整索引列顺序、使用索引提示等方式处理范围查询导致的索引失效。Q3:模糊查询如何优化?A3:可以通过避免使用通配符开头的模糊查询、使用前缀匹配、创建全文索引、使用搜索引擎等方式优化模糊查询。实战问题:Q1:如何诊断索引失效问题?A1:可以通过EXPLAIN分析执行计划、查看慢查询日志、使用性能监控工具、分析索引使用情况等方式诊断索引失效问题。Q2:如何优化联合查询的索引使用?A2:可以通过创建合适的联合索引、优化连接条件、使用索引提示、调整查询顺序等方式优化联合查询的索引使用。Q3:如何处理大数据量下的索引失效?A3:可以通过分表分库、使用分区表、优化索引结构、使用缓存等方式处理大数据量下的索引失效问题。实际案例分析电商订单查询优化:-- 优化前 SELECT * FROM orders WHERE DATE(created_at) = '2023-01-01' AND status = 'PAID' ORDER BY amount DESC; -- 优化后 SELECT * FROM orders WHERE created_at >= '2023-01-01' AND created_at < '2023-01-02' AND status = 'PAID' ORDER BY amount DESC; -- 创建优化索引 CREATE INDEX idx_created_status_amount ON orders(created_at, status, amount); 避免函数使用优化索引结构提高查询效率用户搜索功能优化:-- 优化前 SELECT * FROM users WHERE name LIKE '%John%' OR email LIKE '%john%'; -- 优化后 SELECT * FROM users WHERE name LIKE 'John%' OR email LIKE 'john%'; -- 创建全文索引 CREATE FULLTEXT INDEX idx_search ON users(name, email); 优化模糊查询使用全文索引提升搜索性能面试要点问题分析:索引失效的定义和原因各种失效场景的特点失效带来的影响解决方案:优化查询语句调整索引结构使用替代方案实战经验:常见问题处理优化案例分析性能监控方法总结索引失效的核心原因:最左前缀原则失效:不满足最左前缀匹配函数和运算导致失效:对索引列使用函数或运算范围查询导致失效:使用范围查询条件模糊查询导致失效:使用通配符开头的模糊查询排序和分组导致失效:排序或分组字段顺序不当联合查询导致失效:多表连接条件不当优化策略:遵循最左前缀原则:正确使用联合索引避免函数和运算:直接使用索引列优化范围查询:使用精确匹配或覆盖索引优化模糊查询:避免通配符开头优化排序分组:调整字段顺序优化联合查询:创建合适的索引
  • [技术干货] 【技术合集】2025年10月数据库合集
    📚 合集概览本期技术合集精选了8篇MySQL数据库领域的实战干货,涵盖性能优化、索引设计、并发控制等核心知识点。📖 文章列表1️⃣ 深入分析MySQL死锁的产生原因、检测方法及解决方案核心要点: 详细讲解MySQL死锁的产生原因(如不同顺序访问资源、索引失效等),提供死锁检测方法(SHOW ENGINE INNODB STATUS)和解决方案(统一访问顺序、优化索引、缩短事务时间、死锁重试机制等),帮助开发者有效预防和处理死锁问题。🔗 查看详情2️⃣ 深入分析MySQL执行计划的关键指标及优化策略核心要点: 系统讲解EXPLAIN执行计划的关键字段含义,包括type(访问类型,从const到ALL)、key(使用的索引)、rows(扫描行数)、Extra(额外信息如Using index、Using filesort等),并提供针对性的优化策略,如避免索引失效、优化JOIN查询、消除filesort等。🔗 查看详情3️⃣ 深入分析MySQL中的COUNT机制、性能影响及优化策略核心要点: 对比COUNT()、COUNT(1)、COUNT(主键)、COUNT(字段)的性能差异,解释为什么COUNT()最快(InnoDB优化选择最小索引),并提供大表COUNT优化方案:使用覆盖索引、近似值查询、维护计数表、Redis缓存等,显著提升统计查询性能。🔗 查看详情4️⃣ 深入分析MySQL中的LIMIT机制、性能影响及优化策略核心要点: 分析深度分页性能问题的根本原因(MySQL需扫描offset+limit行然后丢弃前offset行),提供多种优化方案:延迟关联(性能提升10倍+)、基于上次结果的游标分页(性能稳定不受页数影响)、业务层面限制最大页数等。🔗 查看详情5️⃣ 深入分析MySQL中的排序机制、优化策略及常见问题核心要点: 对比两种排序方式:Using index(索引排序,性能最优)和Using filesort(文件排序,性能较差),讲解如何通过创建合适的排序索引、使用覆盖索引、正确使用排序方向、增大sort_buffer_size等方法消除filesort,实现高效排序查询。🔗 查看详情6️⃣ 深入分析MySQL中UUID和自增ID的优缺点及适用场景核心要点: 全面对比UUID和自增ID的优缺点:自增ID性能最优、空间占用小但不适合分布式;UUID全局唯一、分布式友好但性能较差、空间占用大。介绍UUID优化方案(有序UUID、BINARY存储)和分布式ID方案(Snowflake、号段模式),帮助开发者根据业务场景做出正确选择。🔗 查看详情7️⃣ 回表原理及优化核心要点: 解释什么是回表(通过二级索引查询时需要再到聚簇索引获取完整行的过程),分析回表的性能影响(增加IO次数、降低查询速度),提供五种优化方法:覆盖索引(最推荐)、索引下推(ICP)、延迟关联、优化查询字段、合理设计联合索引,有效减少或避免回表操作。🔗 查看详情8️⃣ 索引设计原则核心要点: 总结八大索引设计原则:选择性原则(选择性高的列建索引)、最左前缀原则(联合索引遵循最左匹配)、覆盖索引原则(避免回表)、索引列不使用函数、前缀索引原则(长字符串使用前缀索引)、索引数量控制(单表不超过10个)、区分度优先原则、避免冗余索引,为高性能索引设计提供完整指南。🔗 查看详情9️⃣ 最左匹配原则详解核心要点: 深入讲解联合索引最左匹配原则的本质(索引按a→b→c顺序排序,必须从左边开始匹配)、详细规则(哪些查询可以使用索引、哪些不能)、特殊情况(WHERE条件顺序无关、等值+范围查询、LIKE前缀匹配),并提供索引顺序设计原则:高频+等值+区分度高的字段在前。🔗 查看详情💡 技术要点总结本期合集覆盖MySQL优化的核心领域:性能诊断 - 执行计划分析、死锁检测查询优化 - COUNT优化、分页优化、排序优化、回表优化索引设计 - 索引原则、最左匹配、覆盖索引技术选型 - UUID vs 自增ID的权衡关键数字索引选择性:> 0.8 为优单表索引数:< 10 个深度分页:> 10000 需优化filesort:能避免就避免回表:优先使用覆盖索引✍️ 总结这8篇文章构成了完整的MySQL性能优化知识体系,从问题诊断(执行计划、死锁分析)到具体优化(索引设计、SQL改写),从理论原理(回表机制、最左匹配)到实战方案(分页优化、排序优化),为开发者提供了系统化的MySQL优化指南。💬 欢迎讨论: 你在实际项目中遇到过哪些数据库性能问题?是如何解决的?🔖 记得收藏: 本合集涵盖了MySQL优化的核心知识点,建议收藏备查!
  • [交流吐槽] 【话题交流】为什么大厂越来越偏爱使用 RC(Read Committed)隔离级别?
    RR 听起来更安全,为什么真正的生产库大多用 RC?是性能、锁冲突,还是业务妥协?
  • [技术干货] 深入分析MySQL死锁的产生原因、检测方法及解决方案
    问题描述MySQL死锁是什么?如何产生的?如何检测和诊断死锁?如何避免和解决死锁问题?死锁对系统性能有什么影响?核心答案MySQL死锁的核心要点:基本概念:死锁:两个或多个事务相互等待对方释放资源锁等待:事务等待获取锁的过程死锁检测:MySQL自动检测并处理死锁产生原因:事务并发执行资源循环等待锁的获取顺序不一致解决方案:设置合理的事务隔离级别优化事务执行顺序使用死锁检测和超时机制详细解析1. 死锁产生机制基本场景:-- 事务1 BEGIN; UPDATE users SET name = 'John' WHERE id = 1; UPDATE orders SET status = 1 WHERE user_id = 1; COMMIT; -- 事务2 BEGIN; UPDATE orders SET status = 1 WHERE user_id = 1; UPDATE users SET name = 'John' WHERE id = 1; COMMIT; 事务1和事务2并发执行获取锁的顺序相反导致循环等待锁的类型:行锁:锁定单行数据支持并发访问表锁:锁定整个表影响并发性能间隙锁:锁定索引范围防止幻读死锁条件:互斥条件:资源一次只能被一个事务占用请求与保持:事务持有资源并请求新资源不剥夺条件:已分配的资源不能被强制剥夺循环等待:事务之间形成循环等待链2. 死锁检测与诊断查看死锁日志:-- 查看死锁日志 SHOW ENGINE INNODB STATUS\G -- 查看当前锁等待 SELECT * FROM information_schema.INNODB_TRX; SELECT * FROM information_schema.INNODB_LOCK_WAITS; 死锁日志分析:事务信息:事务ID事务状态等待的锁锁信息:锁类型锁定的资源等待时间死锁图:事务依赖关系循环等待路径监控工具:-- 开启死锁日志 SET GLOBAL innodb_print_all_deadlocks = ON; -- 查看锁等待超时时间 SHOW VARIABLES LIKE 'innodb_lock_wait_timeout'; 3. 死锁预防与解决事务优化:-- 优化前 BEGIN; UPDATE users SET name = 'John' WHERE id = 1; UPDATE orders SET status = 1 WHERE user_id = 1; COMMIT; -- 优化后 BEGIN; -- 按照固定顺序更新 UPDATE orders SET status = 1 WHERE user_id = 1; UPDATE users SET name = 'John' WHERE id = 1; COMMIT; 统一资源访问顺序减少事务持有时间控制事务大小锁优化:-- 使用行锁替代表锁 SELECT * FROM users WHERE id = 1 FOR UPDATE; -- 使用乐观锁 UPDATE users SET name = 'John', version = version + 1 WHERE id = 1 AND version = 1; 使用行级锁考虑乐观锁避免长事务参数优化:-- 设置锁等待超时时间 SET GLOBAL innodb_lock_wait_timeout = 50; -- 设置死锁检测 SET GLOBAL innodb_deadlock_detect = ON; 调整超时时间启用死锁检测优化隔离级别4. 死锁发生后的解决方案自动处理机制:死锁检测:-- 查看死锁检测状态 SHOW VARIABLES LIKE 'innodb_deadlock_detect'; -- 查看死锁日志 SHOW ENGINE INNODB STATUS\GMySQL自动检测死锁选择回滚代价最小的事务释放被回滚事务持有的锁超时机制:-- 设置锁等待超时时间(秒) SET GLOBAL innodb_lock_wait_timeout = 50; 事务等待超时自动回滚避免长时间等待释放被阻塞的资源手动处理步骤:-- 1. 查看当前事务 SELECT * FROM information_schema.INNODB_TRX; -- 2. 查看锁等待情况 SELECT * FROM information_schema.INNODB_LOCK_WAITS; -- 3. 查看死锁日志 SHOW ENGINE INNODB STATUS\G -- 4. 终止死锁事务 KILL <trx_id>; 分析死锁日志识别死锁事务选择回滚目标执行回滚操作系统恢复策略:-- 1. 检查系统状态 SHOW STATUS LIKE 'Innodb_row_lock%'; -- 2. 检查锁等待 SHOW PROCESSLIST; -- 3. 清理死锁事务 SELECT CONCAT('KILL ', id, ';') FROM information_schema.PROCESSLIST WHERE Command = 'Sleep' AND Time > 60; 监控系统状态清理死锁事务恢复系统性能记录死锁信息预防措施加强:-- 1. 调整死锁检测参数 SET GLOBAL innodb_deadlock_detect = ON; SET GLOBAL innodb_print_all_deadlocks = ON; -- 2. 优化事务隔离级别 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 3. 设置事务超时 SET SESSION innodb_lock_wait_timeout = 30; 启用死锁检测记录死锁日志优化事务参数调整隔离级别5. 常见死锁场景并发更新:-- 场景1:并发更新同一行 -- 事务1 UPDATE users SET balance = balance - 100 WHERE id = 1; -- 事务2 UPDATE users SET balance = balance + 100 WHERE id = 1; 批量操作:-- 场景2:批量更新顺序不一致 -- 事务1 UPDATE users SET status = 1 WHERE id IN (1,2,3); -- 事务2 UPDATE users SET status = 2 WHERE id IN (3,2,1); 外键约束:-- 场景3:外键约束导致的死锁 -- 事务1 INSERT INTO orders (user_id) VALUES (1); -- 事务2 DELETE FROM users WHERE id = 1; 常见面试题Q1: 什么是死锁?如何产生的?A: 死锁是指两个或多个事务相互等待对方释放资源:事务并发执行资源循环等待锁的获取顺序不一致满足四个必要条件Q2: 如何避免死锁?A: 可以从以下几个方面避免:统一资源访问顺序减少事务持有时间使用行级锁设置合理的超时时间Q3: 如何诊断死锁?A: 可以通过以下方式诊断:查看死锁日志分析锁等待信息使用监控工具检查事务执行计划实践案例案例一:订单支付-- 优化事务执行顺序 BEGIN; -- 先锁定账户 SELECT * FROM accounts WHERE user_id = 1 FOR UPDATE; -- 再处理订单 UPDATE orders SET status = 'paid' WHERE id = 100; -- 最后更新余额 UPDATE accounts SET balance = balance - 100 WHERE user_id = 1; COMMIT; 案例二:库存管理-- 使用乐观锁避免死锁 BEGIN; -- 先查询当前库存和版本 SELECT stock, version FROM products WHERE id = 1; -- 使用版本号更新 UPDATE products SET stock = stock - 1, version = version + 1 WHERE id = 1 AND version = 1; COMMIT; 记忆技巧死锁产生四条件, 互斥请求不剥夺。 循环等待最关键, 统一顺序可避免。面试要点理解死锁的产生条件掌握死锁的检测方法熟悉常见的解决方案能够分析死锁日志了解死锁对系统性能的影响总结MySQL死锁是并发控制中的重要问题:了解死锁的产生机制掌握死锁的检测方法实施有效的预防措施优化事务的执行顺序合理设置系统参数在实际应用中,应该通过合理的系统设计和优化,最大程度地避免死锁的发生。
  • [技术干货] 深入分析MySQL执行计划的关键指标及优化策略
    问题描述MySQL执行计划是什么?如何查看和分析执行计划?执行计划中的关键指标有哪些?如何根据执行计划优化SQL?核心答案MySQL执行计划的核心要点:基本概念:执行计划:MySQL优化器选择的查询执行路径EXPLAIN:查看执行计划的关键命令优化器:决定执行计划的组件关键指标:type:访问类型,反映查询效率key:实际使用的索引rows:预估扫描行数Extra:额外信息,包含重要提示性能影响:执行计划直接影响查询性能错误的执行计划可能导致全表扫描合理的执行计划可以大幅提升性能详细解析1. 执行计划查看方法基本语法:-- 查看执行计划 EXPLAIN SELECT * FROM users WHERE id = 1; -- 查看详细执行计划 EXPLAIN FORMAT=JSON SELECT * FROM users WHERE id = 1; 执行计划格式:id:查询的序列号select_type:查询类型table:访问的表partitions:匹配的分区type:访问类型possible_keys:可能使用的索引key:实际使用的索引key_len:使用的索引长度ref:索引的哪一列被使用rows:预估扫描行数filtered:过滤后的行数百分比Extra:额外信息2. 关键指标详解type访问类型:-- 查看不同查询的访问类型 EXPLAIN SELECT * FROM users WHERE id = 1; -- const EXPLAIN SELECT * FROM users WHERE name = 'John'; -- ref EXPLAIN SELECT * FROM users WHERE age > 20; -- range EXPLAIN SELECT * FROM users; -- ALL const:通过主键或唯一索引查询eq_ref:多表关联时使用主键或唯一索引ref:使用普通索引查询range:使用索引范围查询index:全索引扫描ALL:全表扫描Extra信息:-- 查看不同查询的Extra信息 EXPLAIN SELECT * FROM users WHERE name = 'John'; -- Using where EXPLAIN SELECT name FROM users WHERE name = 'John'; -- Using index EXPLAIN SELECT * FROM users ORDER BY name; -- Using filesort Using where:使用WHERE条件过滤Using index:使用覆盖索引Using filesort:需要额外排序Using temporary:使用临时表Using join buffer:使用连接缓存3. 执行计划优化索引优化:-- 创建合适的索引 CREATE INDEX idx_name_age ON users(name, age); -- 查看索引使用情况 EXPLAIN SELECT * FROM users WHERE name = 'John' AND age > 20; 确保查询使用合适的索引避免索引失效使用覆盖索引减少回表查询优化:-- 优化前 EXPLAIN SELECT * FROM users WHERE name LIKE '%John%'; -- 优化后 EXPLAIN SELECT * FROM users WHERE name LIKE 'John%'; 避免使用通配符前缀减少排序操作优化连接查询参数优化:-- 查看优化器参数 SHOW VARIABLES LIKE 'optimizer_switch'; -- 调整优化器参数 SET optimizer_switch='index_merge=on'; 调整优化器参数优化统计信息控制执行计划选择4. 常见问题分析全表扫描问题:-- 问题查询 EXPLAIN SELECT * FROM users WHERE age + 1 > 20; -- 优化后 EXPLAIN SELECT * FROM users WHERE age > 19; 避免对索引列进行运算使用合适的索引优化查询条件排序问题:-- 问题查询 EXPLAIN SELECT * FROM users ORDER BY name; -- 优化后 EXPLAIN SELECT * FROM users ORDER BY id; 使用索引排序避免文件排序优化排序字段连接查询问题:-- 问题查询 EXPLAIN SELECT * FROM users u, orders o WHERE u.id = o.user_id; -- 优化后 EXPLAIN SELECT * FROM users u INNER JOIN orders o ON u.id = o.user_id; 使用合适的连接方式确保连接字段有索引控制连接顺序常见面试题Q1: 执行计划中的type字段有哪些值?各代表什么含义?A: type字段表示访问类型,常见值有:const:通过主键或唯一索引查询eq_ref:多表关联时使用主键或唯一索引ref:使用普通索引查询range:使用索引范围查询index:全索引扫描ALL:全表扫描Q2: 如何优化执行计划中的全表扫描?A: 可以从以下几个方面优化:创建合适的索引优化查询条件使用覆盖索引调整优化器参数Q3: Extra字段中的Using filesort表示什么?如何优化?A: Using filesort表示需要额外排序:使用索引排序替代文件排序优化排序字段增加排序缓冲区考虑预排序方案实践案例案例一:索引优化-- 创建复合索引 CREATE INDEX idx_name_age ON users(name, age); -- 查看执行计划 EXPLAIN SELECT * FROM users WHERE name = 'John' AND age > 20 ORDER BY create_time; 案例二:连接优化-- 优化连接查询 EXPLAIN SELECT u.*, o.order_no FROM users u INNER JOIN orders o ON u.id = o.user_id WHERE u.status = 1; 记忆技巧执行计划要关注, type指标最重要。 索引使用要合理, Extra信息别忽略。面试要点理解执行计划的基本概念掌握关键指标的含义熟悉常见的优化策略能够分析执行计划的性能问题了解优化器的工作原理总结MySQL执行计划是优化查询性能的重要工具:关注type指标判断查询效率分析Extra信息发现潜在问题通过索引优化提升查询性能调整优化器参数控制执行计划定期分析执行计划优化查询在实际应用中,应该根据执行计划的分析结果,不断优化SQL查询和数据库结构。
总条数:124 到第
上滑加载中