初级程序员必备的十大技能之数据库基础(三)

简介: 教程来源 http://ltglu.cn/ 本文详解数据库索引优化与事务机制:索引类比书目录,B+树大幅降低IO;详解最左前缀、函数/类型转换等索引失效场景及EXPLAIN分析法;事务部分涵盖ACID、四大隔离级别(解决脏读/不可重复读/幻读)、行锁/乐观锁及秒杀防超卖实战。

四、索引优化:查询加速的核心

4.1 索引的本质
索引就像书的目录,让你不需要翻遍整本书就能找到目标。

没有索引:全表扫描,查询 100 万行需要扫描 100 万次
有索引:B+ 树查找,100 万行只需要约 20 次 IO 操作

4.2 B+ 树索引原理

B+ 树结构:
                 [50]
                /    \
            [30]      [70]
           /   \      /   \
        [20]  [40]  [60]  [80]
         ↓     ↓     ↓     ↓
       数据   数据   数据   数据
       (叶子节点之间用链表连接,方便范围查询)

4.3 索引的最佳实践
哪些列应该建索引?
image.png
复合索引的最左前缀原则

-- 创建复合索引
CREATE INDEX idx_name_age ON users(name, age);

-- ✅ 能使用索引的查询
WHERE name = '张三'              -- 使用索引第1列
WHERE name = '张三' AND age = 25 -- 使用全部索引
WHERE name LIKE '张%'            -- 范围查找,可使用第1列

-- ❌ 不能使用索引的查询
WHERE age = 25                   -- 跳过第1列
WHERE name = '张三' OR age = 25  -- OR 导致索引失效(部分情况)

索引失效的常见场景

-- 1. 对列使用函数
SELECT * FROM users WHERE YEAR(created_at) = 2024;  -- ❌
SELECT * FROM users WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01'; -- ✅

-- 2. 隐式类型转换
SELECT * FROM users WHERE phone = 13800138000;  -- ❌ phone 是 VARCHAR,类型不匹配
SELECT * FROM users WHERE phone = '13800138000'; -- ✅

-- 3. 前导模糊匹配
SELECT * FROM users WHERE name LIKE '%三';    -- ❌
SELECT * FROM users WHERE name LIKE '张%';    -- ✅

-- 4. OR 条件
SELECT * FROM users WHERE name = '张三' OR age = 25;  -- ⚠️ 可能失效

-- 5. NOT 条件
SELECT * FROM users WHERE name NOT IN ('张三', '李四'); -- ⚠️ 效率低

4.4 执行计划分析
使用 EXPLAIN 分析查询语句,是优化 SQL 的必备技能。

EXPLAIN SELECT * FROM users WHERE name = '张三';

-- 输出关键字段解读:
-- type: 访问类型(性能从好到差)
--   system > const > eq_ref > ref > range > index > ALL
--   ALL 表示全表扫描,需要优化!
-- possible_keys: 可能使用的索引
-- key: 实际使用的索引
-- rows: 预估扫描的行数
-- Extra: 额外信息(Using filesort 表示需要额外排序,需要优化)
-- 实际优化案例
-- 慢查询
EXPLAIN SELECT * FROM orders WHERE YEAR(order_date) = 2024;
-- type: ALL, rows: 1000000 (全表扫描)

-- 优化后
ALTER TABLE orders ADD INDEX idx_order_date (order_date);
EXPLAIN SELECT * FROM orders WHERE order_date >= '2024-01-01' AND order_date < '2025-01-01';
-- type: range, rows: 36500 (扫描1年的数据,约3.6万行)

五、事务:要么全做,要么全不做

事务是保证数据一致性的重要机制,尤其在金融、电商等场景。

5.1 什么是事务?
事务是一组 SQL 操作,要么全部成功,要么全部失败。

经典案例:银行转账

-- 张三给李四转账100元
START TRANSACTION;

UPDATE accounts SET balance = balance - 100 WHERE user = '张三';
UPDATE accounts SET balance = balance + 100 WHERE user = '李四';

-- 如果中间出现断电或错误,可以回滚
ROLLBACK;

-- 全部成功后才提交
COMMIT;

5.2 ACID 特性
image.png
5.3 事务的隔离级别
事务隔离级别解决并发事务的问题,但隔离级别越高,性能越差。

-- 查看当前隔离级别
SELECT @@transaction_isolation;

-- 设置隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

image.png
三种问题解释:

-- 1. 脏读:读到未提交的数据
-- 事务A:UPDATE balance SET amount = amount - 100 WHERE id=1;  -- 未提交
-- 事务B:SELECT amount FROM balance WHERE id=1;  -- 读到-100(脏数据)
-- 事务A:ROLLBACK;  -- 事务B读到了不存在的数

-- 2. 不可重复读:同一事务内,同一条记录两次读取结果不同
-- 事务A:SELECT amount FROM balance WHERE id=1;  -- 100
-- 事务B:UPDATE balance SET amount = 200 WHERE id=1; COMMIT;
-- 事务A:SELECT amount FROM balance WHERE id=1;  -- 200(前后不一致)

-- 3. 幻读:同一事务内,两次查询返回的记录数不同
-- 事务A:SELECT COUNT(*) FROM users WHERE age > 18;  -- 10条
-- 事务B:INSERT INTO users(name,age) VALUES('新用户',20); COMMIT;
-- 事务A:SELECT COUNT(*) FROM users WHERE age > 18;  -- 11条(多了1条)

5.4 锁机制

-- 1. 行级锁(InnoDB 默认)
-- 只锁住需要修改的行,并发性能好
SELECT * FROM users WHERE id = 1 FOR UPDATE;  -- 锁定id=1的行

-- 2. 表级锁(MyISAM 默认)
-- 锁住整张表,并发性能差
LOCK TABLES users WRITE;  -- 写锁
LOCK TABLES users READ;   -- 读锁

-- 3. 乐观锁(通过版本号实现)
-- 适用于读多写少的场景
UPDATE products 
SET stock = stock - 1, version = version + 1 
WHERE id = 1 AND version = 5;  -- 只有版本号匹配才更新

5.5 事务实战

-- 电商秒杀场景:防止超卖
START TRANSACTION;

-- 1. 查询库存(使用行锁)
SELECT stock FROM products WHERE id = 1 FOR UPDATE;

-- 2. 检查库存
IF stock > 0 THEN
    -- 3. 更新库存
    UPDATE products SET stock = stock - 1 WHERE id = 1;

    -- 4. 创建订单
    INSERT INTO orders (product_id, user_id, quantity) VALUES (1, 100, 1);

    COMMIT;
ELSE
    ROLLBACK;
END IF;

来源:
http://xbivx.cn/

相关文章
|
2月前
|
编解码 Linux iOS开发
OpenClaw:让经典海盗猫冒险,在现代平台重焕生机
作为1997年经典横版动作游戏《Captain Claw》的开源重制项目,OpenClaw不仅实现了对原版游戏玩法、画面的精准复刻,更通过底层技术优化,解决了原版游戏在现代平台上的运行痛点。与简单的模拟器复刻不同,OpenClaw采用C++从零重构游戏引擎,兼顾了经典体验的还原度与现代设备的性能适配性。本文将从性能优化核心、硬件适配范围、实际场景帧率表现、跨平台性能差异及优化建议五个维度,全面解析OpenClaw的性能优势与潜在提升空间,为玩家提供更具参考价值的体验指南。
|
2月前
|
安全 Java API
别再瞎升级!SpringBoot 2 与 3 全维度核心差异、底层原理与实战避坑
Spring Boot 2 与 3 并非简单版本迭代:前者基于 JDK 8 和 Java EE(javax.*),后者全面升级至 JDK 17+、Jakarta EE 9+(jakarta.*),并原生支持 AOT 编译、虚拟线程、OpenAPI 3、RFC 7807 异常规范及云原生可观测性,架构与生态差异巨大,升级需系统规划与适配。
640 2
|
3月前
|
人工智能 自然语言处理 安全
【新人快速上手使用】小白也能上手的 OpenClaw 2.6.6 安装教程(技术分享)
OpenClaw(小龙虾)是2026年热门开源「数字员工」,支持Windows一键部署(5分钟搞定),本地运行、零代码、全自动办公。无需配置环境,可整理文件、发邮件、浏览器自动化等,隐私安全,小白友好。
|
2月前
|
人工智能 开发框架 Java
Spring 接入 DeepSeek:Java 团队的 AI
Spring携手DeepSeek标志Java生态AI化加速。但仅模型接入远不够,企业亟需一体化AI框架。向量空间JBoltAI应运而生:深度兼容Spring,支持DeepSeek等多模型,内置RAG、Agent编排、私有知识库等能力,助力Java团队高效落地企业级AI应用。(239字)
186 5
|
3月前
|
存储 人工智能 弹性计算
揭秘千问 APP 千万级 AI 订单背后的记忆存储实践
2026年春节,千问 APP “春节请客计划” 9 小时破 1000 万单,依赖 Tablestore 构建的一站式记忆系统:支持短期/长期记忆统一管理、毫秒级读写、Serverless 弹性伸缩、多模态数据融合及原生向量检索,实现数十亿条记忆的高效存储与实时流转。
784 118
|
2月前
|
机器学习/深度学习 人工智能 JSON
别被“HTML 万能论”带偏:Markdown 才是人机协作的真正基石
Claude工程师提出“未来AI只需输出HTML,Markdown已是过去式”的观点。本文从AI底层运行逻辑、Token经济学、注意力机制与真实协作场景出发,指出该观点混淆了表现层与数据层,低估了人类微调的必要性。Markdown之所以不可替代,恰恰因为它信息纯净、容错高、对人与AI都极为友好——它是未来很长一段时间里的“认知JSON”。
251 5
|
3月前
|
SQL 关系型数据库 MySQL
SQL优化十大技巧,查询速度提升10倍!
数据库小学妹带你轻松提速SQL!10个实战优化技巧:精简SELECT、善用LIMIT、巧用EXPLAIN、合理建索引、避开函数索引失效、JOIN优于子查询、IN替代OR、批量操作、EXISTS优化大子查询、定期OPTIMIZE。附避坑指南,新手也能秒上手!
|
3月前
|
存储 缓存 自然语言处理
PHP的OPcache与全栈性能优化——从字节码缓存到预加载
PHP的执行过程分为四个阶段:词法/语法解析→生成抽象语法树(AST)→编译为字节码(opcodes)→执行(ZendVM)
218 9
|
2月前
|
缓存 搜索推荐 网络安全
KKCE:如何解决网站打开慢的问题?
网站打开慢?别急着瞎优化!本文提供一套零门槛、可复用的排查—解决—维护全流程:先用测速工具+浏览器调试精准定位慢因(服务器/资源/网络/本地),再针对性优化(升配、压缩图片、开CDN、配缓存),最后定期测速清理。小白也能3步提速,稳保秒开!(239字)
468 9
|
27天前
|
人工智能 自然语言处理 数据处理
《AI智能体时代,OPC中国为什么开始被关注》
AI智能体正重塑行业协作模式,“OPC中国”聚焦“One Person Company”理念,探索AI时代下轻量化组织、个人能力放大与新型职业教育。它倡导以AI Agent、工作流自动化和多智能体协同为核心,培养个体驾驭复杂任务的新能力。(239字)