首页主机资讯ThinkPHP数据库优化技巧有哪些

ThinkPHP数据库优化技巧有哪些

时间2025-11-27 02:22:03发布访客分类主机资讯浏览1358
导读:ThinkPHP数据库优化技巧清单 一 查询与索引优化 只查需要的字段,避免 **SELECT ***,减少网络与内存开销。示例:field('id,name,email' 。 为高频出现在 WHERE、JOIN、ORDER BY、GRO...

ThinkPHP数据库优化技巧清单

一 查询与索引优化

  • 只查需要的字段,避免 **SELECT ***,减少网络与内存开销。示例:field('id,name,email')
  • 为高频出现在 WHERE、JOIN、ORDER BY、GROUP BY 的字段建立索引;多条件组合使用联合索引并遵循最左前缀原则;外键如 user_id 建议加索引。
  • 避免索引失效:不要在 WHERE 中对字段做函数或计算(如 WHERE YEAR(create_time)=2024),尽量改写为范围或等值条件。
  • 优化分页:列表页优先基于主键/索引列做游标分页(如 where('id','> ',$lastId)-> limit(N)),避免大偏移的 OFFSET
  • 复杂查询使用 EXPLAIN 检查执行计划,关注 type(尽量避免 ALL)、keyrowsExtra 中的 Using filesort/Using temporary
  • 必要时使用原生SQL或查询构造器的子查询/联表,比层层循环更高效。
  • 开启并分析 SQL 日志,定位慢查询与高频 SQL。

二 关联与缓存策略

  • 解决 N+1 查询:在列表场景用 with 预加载一次性取出关联数据,避免在模板或循环中逐条查询。
  • 合理使用查询缓存数据缓存(如 Redis/Memcached):对读多写少、结果较稳定的接口或字典表设置合理 TTL,并在数据变更时主动失效。
  • 区分页面缓存数据缓存的适用场景,避免缓存穿透/雪崩(如设置随机过期、降级兜底)。

三 架构与连接管理

  • 读写分离:在配置中设置主库写、从库读,将报表、搜索等读压力分摊到从库。
  • 分库分表:对大表按业务键拆分,配合中间件或自研路由,降低单库单表压力。
  • 选择合适的缓存与存储:将会话、热点数据、计数等放入 Redis,对日志/非结构化数据考虑 MongoDB
  • 连接管理:避免连接泄露,合理配置连接池与超时;应用侧复用连接、及时释放。

四 监控与数据库配置

  • 慢查询治理:开启 slow_query_loglong_query_time,用 EXPLAIN 与性能工具定位瓶颈。
  • 服务器参数:适当调大 innodb_buffer_pool_size,提升缓冲命中率;合理设置 max_connections 与超时参数。
  • 运行时可观测性:在 config/database.php 记录 SQL 日志,或用 Db::listen 监听 SQL 与耗时,配合 Xdebug/Blackfire 做全链路分析。
  • 生产环境关闭调试模式,减少额外开销。

五 可直接复用的优化示例

  • 列表页预加载 + 游标分页(避免 N+1 与大偏移)
$list = UserModel::with(['profile', 'orders'])
    ->
    where('status', 1)
    ->
    where('id', '>
    ', $lastId)
    ->
    order('id', 'asc')
    ->
    limit(20)
    ->
    select();
    
  • 查询缓存 + 索引提示(稳定字典/配置)
$config = cache('config_dict');

if (!$config) {
    
    $config = ConfigModel::where('status', 1)
        ->
    field('k,v')
        ->
    useIndex('idx_status') // 视库表支持情况使用
        ->
    select()
        ->
    column('v', 'k');
    
    cache('config_dict', $config, 3600);
 // 1小时
}
    
  • 原生 SQL + EXPLAIN 定位慢查询
// 开发/预发环境先分析
$sql = "SELECT u.id,u.name,o.total FROM user u
        JOIN `order` o ON o.user_id = u.id
        WHERE u.status = ? AND o.create_time >
    = ?
        ORDER BY o.create_time DESC LIMIT 50";

Db::listen(function($sql, $runtime) {
    
    // 记录或上报慢 SQL
    if ($runtime >
 0.2) {

        // 告警/写入慢查询日志
    }

}
    );
    
$rows = Db::query($sql, [1, '2025-01-01']);
    
// 用 EXPLAIN 检查是否走索引、是否出现 Using filesort/Using temporary
  • 读写分离配置(示例)
// config/database.php
'connections' =>
     [
    'mysql' =>
     [
        'type'            =>
     'mysql',
        'hostname'        =>
     'write.db.local',
        'database'        =>
     'app',
        'username'        =>
     'write',
        'password'        =>
     '***',
        'deploy'          =>
     1,         // 启用分布式
        'rw_separate'     =>
     true,      // 开启读写分离
        'master_num'      =>
     1,
        'slave_no'        =>
     [],        // 读库序号,可配多个
    ],
]

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: ThinkPHP数据库优化技巧有哪些
本文地址: https://pptw.com/jishu/757412.html
Ubuntu上Fortran多线程编程怎么实现 Ubuntu下Fortran图形界面程序怎么开发

游客 回复需填写必要信息