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

优化国家>地区>城市层级数据查询的更佳编码方案

优化方案:减少数据库查询次数+结构化输出

看起来你现在的脚本虽然能正常运行,但三层嵌套查询存在明显的性能隐患——每次循环都发起独立的数据库请求,当数据量较大时,频繁的数据库交互会拖慢整体响应速度。下面是一套优化方案,既能大幅减少查询次数,还能让代码更简洁易维护:

第一步:用JOIN一次性获取所有关联数据

替代原来的三层嵌套查询,我们可以通过表连接一次性拉取国家、地区、城市的所有关联数据,只需要一次数据库请求:

SELECT 
    c.country_name,
    r.region_name,
    ci.city_name
FROM country c
LEFT JOIN region r ON c.country_id = r.region_country_id
LEFT JOIN city ci ON r.region_id = ci.city_region_id
ORDER BY c.country_name, r.region_name, ci.city_name;

为什么选LEFT JOIN?

如果存在没有下属地区的国家,或者没有下属城市的地区,LEFT JOIN会保留这些条目,避免丢失数据;如果你的业务逻辑里每个国家/地区都有下属层级,也可以换成INNER JOIN来缩小结果集。

第二步:PHP端分组处理结果

拿到一次性查询的结果后,我们只需要在PHP里跟踪当前的国家和地区,就能输出符合要求的层级结构:

// 执行一次性查询
$query = "SELECT 
            c.country_name,
            r.region_name,
            ci.city_name
          FROM country c
          LEFT JOIN region r ON c.country_id = r.region_country_id
          LEFT JOIN city ci ON r.region_id = ci.city_region_id
          ORDER BY c.country_name, r.region_name, ci.city_name";

$result = mysqli_query($mysqli, $query) or die(mysqli_error($mysqli));

// 初始化变量跟踪当前的国家和地区,避免重复输出
$currentCountry = '';
$currentRegion = '';

while ($row = mysqli_fetch_assoc($result)) {
    $countryName = $row['country_name'];
    $regionName = $row['region_name'];
    $cityName = $row['city_name'];

    // 切换国家时输出新的国家标题
    if ($countryName !== $currentCountry) {
        // 非首个国家,先加换行分隔
        if ($currentCountry !== '') {
            echo '<br>';
        }
        echo '<b>' . htmlspecialchars($countryName) . '</b><br>';
        $currentCountry = $countryName;
        $currentRegion = ''; // 切换国家后重置地区跟踪
    }

    // 切换地区时输出新的地区名称
    if ($regionName !== $currentRegion && !empty($regionName)) {
        echo htmlspecialchars($regionName) . '<br>';
        $currentRegion = $regionName;
    }

    // 输出城市(仅当城市存在时)
    if (!empty($cityName)) {
        echo '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' . htmlspecialchars($cityName) . '<br>';
    }
}

优化后的优势

  • 性能提升:从N+M+K次数据库请求减少到1次,大幅降低数据库压力,数据量越大效果越明显
  • 代码简洁:去掉了冗余的嵌套查询逻辑,结构更清晰,后续维护更方便
  • 安全性增强:加入htmlspecialchars处理输出内容,避免XSS注入风险
  • 兼容性更好:通过LEFT JOIN保留了所有层级的数据,不会遗漏无下属的国家/地区

额外优化建议

  • 确保关联字段(region_country_id、city_region_id)都建立了数据库索引,能进一步加快JOIN查询的速度
  • 如果不需要ID字段,就从SELECT语句中移除,减少数据传输量
  • 若后续需要加入动态筛选条件,建议使用mysqli_prepare预处理语句,进一步提升代码安全性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:06:20