本文档风哥主要介绍sqlite数据库索引、执行计划与查询优化相关知识,包括sqlite数据库索引原理、执行计划分析、查询优化原理等内容,风哥教程参考sqlite官方文档Query Planning、Index等内容编写,适合DBA人员和开发人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。
Part01-基础概念与理论知识
1.1 sqlite数据库索引原理
索引是数据库性能优化的核心手段,理解索引原理对于正确使用索引至关重要。更多视频教程www.fgedu.net.cn
1.1.1 sqlite数据库索引类型
1. B-Tree索引
├── 默认索引类型
├── 支持范围查询
├── 支持排序
└── 支持前缀匹配
2. 主键索引
├── 自动创建
├── 表B-Tree的一部分
├── UNIQUE约束
└── 聚集索引
3. 唯一索引
├── UNIQUE约束自动创建
├── 保证值唯一
├── 允许NULL值
└── 用于数据完整性
4. 复合索引
├── 多列组合索引
├── 支持最左前缀
├── 列顺序重要
└── 减少索引数量
5. 部分索引
├── 条件过滤索引
├── 减少索引大小
├── 提高写入性能
└── 适合特定场景
6. 表达式索引
├── 索引表达式结果
├── 支持函数索引
├── 3.9.0+版本支持
└── 特殊查询优化
1.1.2 sqlite数据库索引结构
索引B-Tree特点:
├── 键:索引列值 + ROWID
├── 值:无(仅存储键)
├── 排序:按键值升序
└── 查找:二分查找
B-Tree结构示意:
根页
│
┌───────────┼───────────┐
↓ ↓ ↓
中间页 中间页 中间页
│ │ │
┌─────┼─────┐ ┌─────┼─────┐ ┌─────┼─────┐
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
叶子页 叶子页 叶子页 叶子页 叶子页 叶子页 叶子页 叶子页 叶子页
(存储索引键+ROWID)
索引存储格式:
┌────────────────────────────────────┐
│ 索引列1值 │ 索引列2值 │ … │ ROWID │
└────────────────────────────────────┘
索引查找过程:
1. 从根页开始
2. 二分查找确定子页
3. 递归到叶子页
4. 找到ROWID
5. 通过ROWID访问表数据
1.2 sqlite数据库执行计划分析
执行计划是查询优化器生成的查询执行方案,分析执行计划是优化查询的关键。学习交流加群风哥微信: itpux-com
1.2.1 EXPLAIN命令详解
1. EXPLAIN QUERY PLAN
├── 显示查询执行计划
├── 人类可读格式
└── 推荐使用
2. EXPLAIN
├── 显示虚拟机指令
├── 底层详细
└── 调试用
执行计划输出格式:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_users WHERE id = 1;
QUERY PLAN
`–SEARCH TABLE fgedu_users USING INTEGER PRIMARY KEY (rowid=?)
执行计划关键字:
├── SCAN:全表扫描
├── SEARCH:索引查找
├── USING INDEX:使用索引
├── USING COVERING INDEX:覆盖索引
├── USING INTEGER PRIMARY KEY:主键查找
├── TEMP B-TREE:临时B-Tree(排序)
└── SUBQUERY:子查询
扫描类型对比:
┌─────────────────┬──────────────────────────┐
│ 类型 │ 说明 │
├─────────────────┼──────────────────────────┤
│ SCAN TABLE │ 全表扫描,性能较差 │
│ SEARCH TABLE │ 索引查找,性能较好 │
│ SCAN INDEX │ 索引全扫描 │
│ SEARCH INDEX │ 索引范围查找 │
└─────────────────┴──────────────────────────┘
1.2.2 执行计划分析示例
1. 全表扫描:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_users;
QUERY PLAN
`–SCAN TABLE fgedu_users
2. 主键查找:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_users WHERE id = 1;
QUERY PLAN
`–SEARCH TABLE fgedu_users USING INTEGER PRIMARY KEY (rowid=?)
3. 索引查找:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_users WHERE email = ‘test@fgedu.net.cn’;
QUERY PLAN
`–SEARCH TABLE fgedu_users USING INDEX idx_users_email (email=?)
4. 复合索引查找:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE user_id = 1 AND status = ‘pending’;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_status (user_id=? AND status=?)
5. 覆盖索引:
sqlite> EXPLAIN QUERY PLAN SELECT email FROM fgedu_users WHERE email LIKE ‘test%’;
QUERY PLAN
`–SEARCH TABLE fgedu_users USING COVERING INDEX idx_users_email (email>? AND email)
6. 排序使用临时表:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_users ORDER BY created_at;
QUERY PLAN
|–SCAN TABLE fgedu_users
`–USE TEMP B-TREE FOR ORDER BY
7. 多表连接:
sqlite> EXPLAIN QUERY PLAN SELECT u.name, o.order_no
…> FROM fgedu_users u
…> JOIN fgedu_orders o ON u.id = o.user_id;
QUERY PLAN
|–SCAN TABLE fgedu_users AS u
`–SEARCH TABLE fgedu_orders AS o USING INDEX idx_orders_user_id (user_id=?)
1.3 sqlite数据库查询优化原理
理解sqlite查询优化器的工作原理,有助于编写高效的SQL语句。更多学习教程公众号风哥教程itpux_com
1.3.1 查询优化器工作原理
优化过程:
1. 解析SQL语句
├── 词法分析
├── 语法分析
└── 生成语法树
2. 查询重写
├── 常量折叠
├── 子查询展开
└── 视图展开
3. 生成执行计划
├── 选择访问路径
├── 选择连接顺序
├── 选择连接方法
└── 估算成本
4. 选择最优计划
├── 基于成本优化
├── 使用统计信息
└── 选择最低成本计划
优化器统计信息:
├── sqlite_stat1:表和索引统计
├── sqlite_stat4:列值分布(可选)
└── 通过ANALYZE命令更新
统计信息示例:
sqlite> SELECT * FROM sqlite_stat1;
tbl idx stat
———– —————- ———–
fgedu_users idx_users_email 10000 1
fgedu_orders idx_orders_user 50000 5
更新统计信息:
sqlite> ANALYZE;
Part02-生产环境规划与建议
2.1 sqlite数据库索引规划建议
合理的索引规划是数据库性能优化的基础。风哥提示:索引是一把双刃剑,需要权衡查询性能和写入性能。
2.1.1 索引设计原则
1. 选择性原则
├── 高选择性列优先
├── 唯一值比例高
├── 区分度好
└── 避免低选择性列
2. 最左前缀原则
├── 复合索引从左匹配
├── 查询条件顺序
├── 列顺序重要
└── 考虑查询模式
3. 覆盖索引原则
├── 包含查询所需列
├── 避免回表
├── 提高查询性能
└── 减少IO
4. 适度原则
├── 避免过多索引
├── 考虑写入开销
├── 定期清理无用索引
└── 监控索引使用
索引数量建议:
┌─────────────────┬──────────────────────────┐
│ 表大小 │ 建议索引数量 │
├─────────────────┼──────────────────────────┤
│ 小表(<1万) │ 1-3个 │
│ 中表(1-100万) │ 3-5个 │
│ 大表(>100万) │ 5-10个 │
└─────────────────┴──────────────────────────┘
索引列选择优先级:
├── 1. WHERE条件列
├── 2. JOIN关联列
├── 3. ORDER BY排序列
├── 4. GROUP BY分组列
└── 5. SELECT列(覆盖索引)
2.2 sqlite数据库查询规划建议
合理的查询规划可以显著提高数据库性能。学习交流加群风哥微信: itpux-com
2.2.1 查询优化建议
1. 避免全表扫描
├── 使用WHERE条件
├── 创建合适索引
├── 使用LIMIT限制
└── 分析执行计划
2. 优化WHERE条件
├── 使用索引列
├── 避免函数操作
├── 避免隐式转换
└── 使用合适操作符
3. 优化JOIN
├── 小表驱动大表
├── 创建关联列索引
├── 减少JOIN表数量
└── 使用合适的JOIN类型
4. 优化子查询
├── 使用JOIN替代
├── 使用EXISTS替代IN
├── 避免相关子查询
└── 使用CTE
5. 优化排序
├── 使用索引排序
├── 避免大数据量排序
├── 使用LIMIT
└── 考虑覆盖索引
查询优化检查清单:
├── [ ] 是否使用了索引?
├── [ ] 是否有全表扫描?
├── [ ] 是否有临时表?
├── [ ] JOIN顺序是否合理?
├── [ ] 子查询是否可优化?
└── [ ] 排序是否使用索引?
2.3 sqlite数据库性能规划建议
完善的性能规划可以确保数据库稳定高效运行。更多学习教程公众号风哥教程itpux_com
2.3.1 性能监控规划
1. 监控指标
├── 查询响应时间
├── 查询吞吐量
├── 索引命中率
├── 全表扫描次数
└── 慢查询数量
2. 监控方法
├── 应用层日志
├── 数据库日志
├── PRAGMA命令
└── 定期分析
3. 告警阈值
├── 慢查询:>1秒
├── 全表扫描:>1000行
├── 索引命中率:<80%
└── 响应时间:>500ms
4. 优化流程
├── 识别慢查询
├── 分析执行计划
├── 制定优化方案
├── 实施优化
└── 验证效果
性能监控脚本:
#!/bin/bash
# perf_monitor.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
DB=”/sqlite/fgdata/fgedudb.db”
echo “=== SQLite Performance Monitor ===”
echo “Time: $(date)”
echo “Database Size:”
sqlite3 $DB “SELECT (page_count * page_size) / 1024.0 / 1024.0 as size_mb FROM pragma_page_count, pragma_page_size;”
echo “Index Stats:”
sqlite3 $DB “SELECT * FROM sqlite_stat1 LIMIT 10;”
echo “Integrity Check:”
sqlite3 $DB “PRAGMA quick_check;”
Part03-生产环境项目实施方案
3.1 sqlite数据库索引管理实战
以下是sqlite数据库索引管理的实际操作。学习交流加群风哥QQ113257174
3.1.1 创建索引
sqlite> CREATE TABLE fgedu_orders (
…> id INTEGER PRIMARY KEY AUTOINCREMENT,
…> order_no TEXT NOT NULL,
…> user_id INTEGER NOT NULL,
…> product_id INTEGER NOT NULL,
…> quantity INTEGER DEFAULT 1,
…> price REAL NOT NULL,
…> status TEXT DEFAULT ‘pending’,
…> created_at DATETIME DEFAULT CURRENT_TIMESTAMP
…> );
创建单列索引:
sqlite> CREATE INDEX idx_orders_user_id ON fgedu_orders(user_id);
sqlite> CREATE INDEX idx_orders_status ON fgedu_orders(status);
创建唯一索引:
sqlite> CREATE UNIQUE INDEX idx_orders_order_no ON fgedu_orders(order_no);
创建复合索引:
sqlite> CREATE INDEX idx_orders_user_status ON fgedu_orders(user_id, status);
sqlite> CREATE INDEX idx_orders_created ON fgedu_orders(created_at DESC);
创建部分索引:
sqlite> CREATE INDEX idx_orders_pending ON fgedu_orders(user_id)
…> WHERE status = ‘pending’;
创建表达式索引:
sqlite> CREATE INDEX idx_orders_month ON fgedu_orders(strftime(‘%Y-%m’, created_at));
查看索引:
sqlite> .indices fgedu_orders
idx_orders_created
idx_orders_order_no
idx_orders_pending
idx_orders_status
idx_orders_user_id
idx_orders_user_status
查看索引定义:
sqlite> .schema idx_orders_user_status
CREATE INDEX idx_orders_user_status ON fgedu_orders(user_id, status);
3.1.2 索引维护
sqlite> REINDEX idx_orders_user_id;
sqlite> REINDEX fgedu_orders;
删除索引:
sqlite> DROP INDEX IF EXISTS idx_orders_month;
更新统计信息:
sqlite> ANALYZE;
sqlite> ANALYZE fgedu_orders;
查看统计信息:
sqlite> SELECT * FROM sqlite_stat1 WHERE tbl = ‘fgedu_orders’;
tbl idx stat
———– ———————- ———–
fgedu_orders idx_orders_user_id 100000 10
fgedu_orders idx_orders_status 100000 33333
fgedu_orders idx_orders_user_status 100000 10 2
查看索引使用情况:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE user_id = 100;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_id (user_id=?)
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE user_id = 100 AND status = ‘pending’;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_status (user_id=? AND status=?)
索引维护脚本:
#!/bin/bash
# index_maintenance.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
DB=”/sqlite/fgdata/fgedudb.db”
echo “=== Index Maintenance ===”
echo “Time: $(date)”
echo “Updating statistics…”
sqlite3 $DB “ANALYZE;”
echo “Index list:”
sqlite3 $DB “SELECT name, tbl_name FROM sqlite_master WHERE type=’index’ AND name NOT LIKE ‘sqlite_%’;”
echo “Index statistics:”
sqlite3 $DB “SELECT * FROM sqlite_stat1;”
echo “Maintenance completed”
3.2 sqlite数据库执行计划分析实战
以下是sqlite数据库执行计划分析的实际操作。风哥提示:执行计划分析是查询优化的核心技能。
3.2.1 执行计划分析示例
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE id = 1000;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INTEGER PRIMARY KEY (rowid=?)
分析条件查询:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE user_id = 100;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_id (user_id=?)
分析复合条件查询:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders
…> WHERE user_id = 100 AND status = ‘pending’;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_status (user_id=? AND status=?)
分析排序查询:
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders ORDER BY created_at DESC LIMIT 10;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_created
分析JOIN查询:
sqlite> EXPLAIN QUERY PLAN
…> SELECT u.username, o.order_no, o.price
…> FROM fgedu_users u
…> JOIN fgedu_orders o ON u.id = o.user_id
…> WHERE u.status = 1;
QUERY PLAN
|–SEARCH TABLE fgedu_users AS u USING INDEX idx_users_status (status=?)
`–SEARCH TABLE fgedu_orders AS o USING INDEX idx_orders_user_id (user_id=?)
分析聚合查询:
sqlite> EXPLAIN QUERY PLAN
…> SELECT user_id, COUNT(*) as order_count, SUM(price) as total
…> FROM fgedu_orders
…> GROUP BY user_id
…> ORDER BY total DESC;
QUERY PLAN
|–SCAN TABLE fgedu_orders USING COVERING INDEX idx_orders_user_id
`–USE TEMP B-TREE FOR ORDER BY
分析子查询:
sqlite> EXPLAIN QUERY PLAN
…> SELECT * FROM fgedu_users
…> WHERE id IN (SELECT user_id FROM fgedu_orders WHERE status = ‘pending’);
QUERY PLAN
|–SEARCH TABLE fgedu_users USING INTEGER PRIMARY KEY (rowid=?)
`–SCAN TABLE fgedu_orders USING COVERING INDEX idx_orders_user_status
3.2.2 执行计划优化示例
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE price > 100;
QUERY PLAN
`–SCAN TABLE fgedu_orders
创建索引优化:
sqlite> CREATE INDEX idx_orders_price ON fgedu_orders(price);
优化后:索引扫描
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE price > 100;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_price (price>?)
优化前:排序使用临时表
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE user_id = 100 ORDER BY created_at;
QUERY PLAN
|–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_id (user_id=?)
`–USE TEMP B-TREE FOR ORDER BY
创建复合索引优化:
sqlite> CREATE INDEX idx_orders_user_created ON fgedu_orders(user_id, created_at);
优化后:索引排序
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE user_id = 100 ORDER BY created_at;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_created (user_id=?)
优化前:覆盖索引
sqlite> EXPLAIN QUERY PLAN SELECT user_id, status FROM fgedu_orders WHERE user_id = 100;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING COVERING INDEX idx_orders_user_status (user_id=?)
3.3 sqlite数据库查询优化实战
以下是sqlite数据库查询优化的实际操作。更多视频教程www.fgedu.net.cn
3.3.1 查询优化示例
— 优化前
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE user_id = 100;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_id (user_id=?)
— 优化后:只选择需要的列
sqlite> EXPLAIN QUERY PLAN SELECT order_no, price FROM fgedu_orders WHERE user_id = 100;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING COVERING INDEX idx_orders_user_id (user_id=?)
优化2:使用覆盖索引
sqlite> CREATE INDEX idx_orders_cover ON fgedu_orders(user_id, order_no, price);
sqlite> EXPLAIN QUERY PLAN SELECT order_no, price FROM fgedu_orders WHERE user_id = 100;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING COVERING INDEX idx_orders_cover (user_id=?)
优化3:避免函数操作
— 优化前:函数导致索引失效
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE strftime(‘%Y-%m’, created_at) = ‘2024-04’;
QUERY PLAN
`–SCAN TABLE fgedu_orders
— 优化后:范围查询
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders
…> WHERE created_at >= ‘2024-04-01’ AND created_at < '2024-05-01';
QUERY PLAN
`--SEARCH TABLE fgedu_orders USING INDEX idx_orders_created (created_at>? AND created_at)
优化4:使用EXISTS替代IN
-- 优化前
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_users
…> WHERE id IN (SELECT user_id FROM fgedu_orders);
QUERY PLAN
|–SCAN TABLE fgedu_users
`–SCAN TABLE fgedu_orders USING COVERING INDEX idx_orders_user_id
— 优化后
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_users u
…> WHERE EXISTS (SELECT 1 FROM fgedu_orders o WHERE o.user_id = u.id);
QUERY PLAN
|–SCAN TABLE fgedu_users AS u
`–CORRELATED SCALAR SUBQUERY 1
`–SEARCH TABLE fgedu_orders AS o USING INDEX idx_orders_user_id (user_id=?)
3.3.2 慢查询分析
#!/bin/bash
# slow_query_analyze.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
DB=”/sqlite/fgdata/fgedudb.db”
echo “=== Slow Query Analysis ===”
echo “Time: $(date)”
# 测试查询1
echo “Query 1: SELECT * FROM fgedu_orders WHERE user_id = 100”
time sqlite3 $DB “SELECT COUNT(*) FROM fgedu_orders WHERE user_id = 100;”
sqlite3 $DB “EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE user_id = 100;”
# 测试查询2
echo “Query 2: SELECT * FROM fgedu_orders WHERE status = ‘pending'”
time sqlite3 $DB “SELECT COUNT(*) FROM fgedu_orders WHERE status = ‘pending’;”
sqlite3 $DB “EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE status = ‘pending’;”
# 测试查询3
echo “Query 3: SELECT * FROM fgedu_orders ORDER BY created_at DESC LIMIT 10”
time sqlite3 $DB “SELECT id, order_no FROM fgedu_orders ORDER BY created_at DESC LIMIT 10;”
sqlite3 $DB “EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders ORDER BY created_at DESC LIMIT 10;”
echo “Analysis completed”
执行结果:
$ ./slow_query_analyze.sh
=== Slow Query Analysis ===
Time: Mon Apr 8 11:00:00 CST 2024
Query 1: SELECT * FROM fgedu_orders WHERE user_id = 100
COUNT(*)
——–
15
real 0m0.005s
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_id (user_id=?)
Part04-生产案例与实战讲解
4.1 sqlite数据库索引优化案例
以下是sqlite数据库索引优化的实际案例。学习交流加群风哥微信: itpux-com
4.1.1 电商订单索引优化案例
问题分析:
1. 查询用户订单列表慢
2. 查询待处理订单慢
3. 订单统计查询慢
初始索引:
├── PRIMARY KEY (id)
└── UNIQUE (order_no)
优化方案:
1. 用户订单查询优化:
sqlite> CREATE INDEX idx_orders_user_created ON fgedu_orders(user_id, created_at DESC);
— 优化前
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE user_id = 100 ORDER BY created_at DESC;
QUERY PLAN
|–SCAN TABLE fgedu_orders
`–USE TEMP B-TREE FOR ORDER BY
— 优化后
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE user_id = 100 ORDER BY created_at DESC;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_created (user_id=?)
2. 待处理订单查询优化:
sqlite> CREATE INDEX idx_orders_status_created ON fgedu_orders(status, created_at);
— 优化前
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE status = ‘pending’ ORDER BY created_at;
QUERY PLAN
|–SCAN TABLE fgedu_orders
`–USE TEMP B-TREE FOR ORDER BY
— 优化后
sqlite> EXPLAIN QUERY PLAN SELECT * FROM fgedu_orders WHERE status = ‘pending’ ORDER BY created_at;
QUERY PLAN
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_status_created (status=?)
3. 订单统计优化:
sqlite> CREATE INDEX idx_orders_user_status_price ON fgedu_orders(user_id, status, price);
性能对比:
┌─────────────────┬──────────┬──────────┐
│ 查询 │ 优化前 │ 优化后 │
├─────────────────┼──────────┼──────────┤
│ 用户订单列表 │ 500ms │ 5ms │
│ 待处理订单 │ 1000ms │ 10ms │
│ 订单统计 │ 2000ms │ 20ms │
└─────────────────┴──────────┴──────────┘
4.2 sqlite数据库查询优化案例
以下是sqlite数据库查询优化的实际案例。风哥提示:查询优化需要结合具体业务场景。
4.2.1 复杂查询优化案例
原始查询:
sqlite> SELECT
…> u.username,
…> COUNT(o.id) as order_count,
…> SUM(o.price) as total_amount,
…> AVG(o.price) as avg_amount
…> FROM fgedu_users u
…> LEFT JOIN fgedu_orders o ON u.id = o.user_id
…> GROUP BY u.id
…> ORDER BY total_amount DESC;
执行计划:
QUERY PLAN
|–SCAN TABLE fgedu_users
`–SEARCH TABLE fgedu_orders USING INDEX idx_orders_user_id (user_id=?)
优化方案1:使用覆盖索引
sqlite> CREATE INDEX idx_orders_user_stats ON fgedu_orders(user_id, price);
优化方案2:预计算统计
sqlite> CREATE TABLE fgedu_user_stats (
…> user_id INTEGER PRIMARY KEY,
…> order_count INTEGER DEFAULT 0,
…> total_amount REAL DEFAULT 0,
…> updated_at DATETIME
…> );
sqlite> INSERT INTO fgedu_user_stats (user_id, order_count, total_amount)
…> SELECT user_id, COUNT(*), SUM(price)
…> FROM fgedu_orders
…> GROUP BY user_id;
优化后查询:
sqlite> SELECT
…> u.username,
…> s.order_count,
…> s.total_amount,
…> s.total_amount / s.order_count as avg_amount
…> FROM fgedu_users u
…> JOIN fgedu_user_stats s ON u.id = s.user_id
…> ORDER BY s.total_amount DESC;
性能对比:
┌─────────────────┬──────────┬──────────┐
│ 方案 │ 执行时间 │ 扫描行数 │
├─────────────────┼──────────┼──────────┤
│ 原始查询 │ 2000ms │ 100000 │
│ 覆盖索引 │ 500ms │ 100000 │
│ 预计算统计 │ 10ms │ 10000 │
└─────────────────┴──────────┴──────────┘
4.3 sqlite数据库性能优化案例
以下是sqlite数据库性能优化的实际案例。更多学习教程公众号风哥教程itpux_com
4.3.1 全局性能优化案例
初始状态:
├── TPS: 50
├── 平均响应时间: 500ms
├── 慢查询率: 10%
└── 错误率: 5%
优化步骤:
1. 启用WAL模式:
sqlite> PRAGMA journal_mode = WAL;
2. 配置缓存:
sqlite> PRAGMA cache_size = -64000;
3. 创建必要索引:
sqlite> ANALYZE;
sqlite> — 根据慢查询创建索引
4. 优化查询:
sqlite> — 重写慢查询
sqlite> — 使用覆盖索引
5. 配置连接池:
pool_size = 20
max_overflow = 10
优化后状态:
├── TPS: 500
├── 平均响应时间: 50ms
├── 慢查询率: 0.1%
└── 错误率: 0.01%
性能提升:
├── TPS提升: 10倍
├── 响应时间降低: 90%
├── 慢查询率降低: 99%
└── 错误率降低: 99.8%
优化脚本:
#!/bin/bash
# db_optimize.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
DB=”/sqlite/fgdata/fgedudb.db”
echo “=== Database Optimization ===”
sqlite3 $DB < 基于多年的实践经验,以下是sqlite数据库索引的最佳实践总结。学习交流加群风哥QQ113257174 1. 索引设计 2. 索引维护 3. 索引监控 4. 索引优化 索引设计检查清单: 以下是sqlite数据库查询优化的技巧总结。from sqlite视频:www.itpux.com 1. 查询编写 2. 条件优化 3. JOIN优化 4. 子查询优化 5. 排序优化 查询优化检查清单: 综合各种因素,以下是sqlite数据库性能优化的总结。更多视频教程www.fgedu.net.cn 索引优化: 查询优化: 配置优化: 监控优化: 优化流程: 本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.htmlPart05-风哥经验总结与分享
5.1 sqlite数据库索引最佳实践
5.1.1 索引最佳实践总结
├── 高选择性列优先
├── 复合索引注意列顺序
├── 考虑覆盖索引
└── 适度创建索引
├── 定期更新统计信息
├── 监控索引使用情况
├── 清理无用索引
└── 重建碎片化索引
├── 监控索引命中率
├── 监控索引大小
├── 监控索引碎片
└── 监控写入性能
├── 分析执行计划
├── 识别缺失索引
├── 识别冗余索引
└── 持续优化调整
├── [ ] WHERE条件列是否有索引?
├── [ ] JOIN关联列是否有索引?
├── [ ] 排序列是否有索引?
├── [ ] 复合索引列顺序是否合理?
├── [ ] 是否有覆盖索引?
├── [ ] 索引数量是否合理?
└── [ ] 是否定期维护索引?
5.2 sqlite数据库查询优化技巧
5.2.1 查询优化技巧汇总
├── 避免SELECT *
├── 使用覆盖索引
├── 避免函数操作
└── 合理使用LIMIT
├── 使用索引列
├── 避免隐式转换
├── 使用合适操作符
└── 避免OR条件
├── 小表驱动大表
├── 创建关联索引
├── 减少JOIN数量
└── 选择合适JOIN类型
├── 使用JOIN替代
├── 使用EXISTS替代IN
├── 使用CTE
└── 避免相关子查询
├── 使用索引排序
├── 减少排序数据量
└── 使用LIMIT
├── [ ] 是否使用索引?
├── [ ] 是否有全表扫描?
├── [ ] 是否有临时表?
├── [ ] JOIN是否合理?
├── [ ] 子查询是否可优化?
├── [ ] 排序是否使用索引?
└── [ ] 是否有隐式转换?
5.3 sqlite数据库性能优化总结
5.3.1 性能优化总结
├── 创建必要的索引
├── 使用复合索引
├── 使用覆盖索引
├── 定期维护索引
└── 监控索引使用
├── 分析执行计划
├── 避免全表扫描
├── 优化JOIN
├── 优化子查询
└── 使用覆盖索引
├── 启用WAL模式
├── 配置缓存大小
├── 设置同步模式
├── 配置连接池
└── 定期维护
├── 监控慢查询
├── 监控索引使用
├── 监控响应时间
├── 监控错误率
└── 持续优化
├── 1. 识别性能问题
├── 2. 分析根本原因
├── 3. 制定优化方案
├── 4. 实施优化
├── 5. 验证效果
└── 6. 持续监控
