You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中优化构建关联关系并高效统计数据?

优化点击量统计性能并建立关联关系

一、建立模型关联

在Country模型中定义与Hit的一对多关联,直接绑定type = 'cities'的过滤条件,后续查询更简洁:

// app/Models/Country.php
public function cityHits()
{
    return $this->hasMany(Hit::class)->where('type', 'cities');
}

二、核心性能优化方案

1. 合并查询减少数据库请求

原代码分两次查询Country和Hit,改用关联查询合并为一次数据库交互:

$country = Country::where('key', strip_tags($key))->first();
$count = $country ? $country->cityHits()->distinct('type_id')->count() : 0;

2. 添加联合索引(最关键优化)

慢查询的核心原因通常是缺少合适索引,给hits表创建覆盖查询条件的联合索引:

CREATE INDEX idx_hits_type_country_typeid ON hits (type, country_id, type_id);

该索引覆盖了WHERE过滤的type、country_id,以及DISTINCT用到的type_id,数据库可直接通过索引完成统计,无需扫描全表。

3. 简化不必要的处理

如果country表的key字段入库时已做过清洗(无HTML标签),直接移除strip_tags减少PHP层面的开销:

$country = Country::where('key', $key)->first();

4. 原生SQL进一步提升效率

若ORM封装仍有性能损耗,可直接使用原生联合查询:

$count = DB::selectOne("
    SELECT COUNT(DISTINCT type_id) AS count
    FROM hits
    JOIN countries ON hits.country_id = countries.id
    WHERE countries.key = ? AND hits.type = 'cities'
", [strip_tags($key)])->count;

三、额外优化建议

  • 缓存非实时数据:若统计结果不需要实时更新,用Redis缓存统计值,降低数据库查询频率:
$cacheKey = "country_city_hits_{$key}";
$count = Cache::remember($cacheKey, 300, function () use ($key) {
    return Country::where('key', strip_tags($key))
        ->first()
        ->cityHits()
        ->distinct('type_id')
        ->count();
});
  • 数据归档/分表:若hits表数据量极大,可按时间分表或归档历史数据,减少单表数据规模。

内容的提问来源于stack exchange,提问作者micky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:22:15