From 6aa3417855248b30f2c177240c74ce5be9345804 Mon Sep 17 00:00:00 2001 From: hoteas <925970985@qq.com> Date: Sun, 17 May 2026 04:08:54 +0800 Subject: [PATCH] =?UTF-8?q?refactor(code):=20=E4=BC=98=E5=8C=96=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=81=9A=E5=90=88=E6=9F=A5=E8=AF=A2=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=B8=8E=E6=9D=A1=E4=BB=B6=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构数据聚合查询流程,减少多次数据库查询,提升性能 - 引入聚合表达式列表和元数据结构,简化查询逻辑 - 优化条件判断,确保不必要的字段被正确过滤 - 改进区域统计逻辑,使用单次查询替代逐个计数,提高效率 - 更新搜索功能,确保请求数据的有效性 --- code.go | 181 +++++++++++++++++++++++------------------------ code/makecode.go | 4 +- 2 files changed, 91 insertions(+), 94 deletions(-) diff --git a/code.go b/code.go index a3124ad..c057781 100644 --- a/code.go +++ b/code.go @@ -754,105 +754,100 @@ var TptProject = Proj{ //if pageSize <= 0 { // pageSize = 20 //} - redData := Map{} + redData := Map{} - data["count"] = that.Db.Count(tableName, where) - testQu := []string{} - testQuData := that.MakeCodeRouter[hotimeName].TableColumns[tableName] - for key, _ := range testQuData { - //fmt.Println(key, ":", value) - testQu = append(testQu, key) + data["count"] = that.Db.Count(tableName, where) + testQu := []string{} + testQuData := that.MakeCodeRouter[hotimeName].TableColumns[tableName] + for key := range testQuData { + testQu = append(testQu, key) + } + sort.Strings(testQu) + + // 第一步:扫描所有字段,构建聚合表达式列表和元数据 + type selectOptMeta struct { + ops Slice + vals []string + } + caseParts := []string{} + selectMetas := map[string]*selectOptMeta{} + sumFieldKeys := []string{} + hasAreaId := false + + for _, k := range testQu { + v := testQuData[k] + if v.GetBool("notUse") { continue } + if strings.Contains(k, "state") { continue } + if strings.Contains(k, "scope") { continue } + if strings.Contains(k, "_code") { continue } + + switch v.GetString("type") { + case "select": + ops := v.GetSlice("options") + sm := &selectOptMeta{ops: ops} + for k1 := range ops { + v1 := ops.GetMap(k1) + val := v1.GetString("value") + sm.vals = append(sm.vals, val) + safeVal := strings.ReplaceAll(val, "'", "''") + alias := fmt.Sprintf("__sel__%s__%d", k, k1) + caseParts = append(caseParts, + fmt.Sprintf("SUM(CASE WHEN `%s`='%s' THEN 1 ELSE 0 END) AS `%s`", k, safeVal, alias)) + } + selectMetas[k] = sm + + case "number": + if strings.Contains(k, "area_id") { hasAreaId = true; continue } + if strings.Contains(k, "_id") { continue } + if k == "id" { continue } + if strings.Contains(k, "percent") { continue } + if strings.Contains(k, "exp_") { continue } + if strings.Contains(k, "side") { continue } + if strings.Contains(k, "lat") { continue } + if strings.Contains(k, "lng") { continue } + if strings.Contains(k, "distance") { continue } + alias := "__sum__" + k + caseParts = append(caseParts, fmt.Sprintf("SUM(`%s`) AS `%s`", k, alias)) + sumFieldKeys = append(sumFieldKeys, k) } - sort.Strings(testQu) - for _, k := range testQu { - v := testQuData[k] - //不可使用,未在前端展示,但在内存中保持有 - if v.GetBool("notUse") { + } - continue + // 第二步:单次聚合查询替代原来 N×M+K 次串行查询 + if len(caseParts) > 0 { + aggRow := that.Db.Get(tableName, strings.Join(caseParts, ","), where) + if aggRow != nil { + // 回填 select 字段各选项的 count + for k, sm := range selectMetas { + for k1 := range sm.ops { + v1 := sm.ops.GetMap(k1) + alias := fmt.Sprintf("__sel__%s__%d", k, k1) + v1["count"] = aggRow.GetCeilInt64(alias) + sm.ops[k1] = v1 + } + redData[k] = sm.ops } - - if strings.Contains(k, "state") { - continue + // 回填 number 字段的 sum + for _, k := range sumFieldKeys { + alias := "__sum__" + k + redData[k] = aggRow[alias] } - if strings.Contains(k, "scope") { - continue - } - if strings.Contains(k, "_code") { - continue - } - //检索查询 - if v.GetString("type") == "select" { - - ops := v.GetSlice("options") - for k1, _ := range ops { - v1 := ops.GetMap(k1) - where1 := DeepCopyMap(where).(Map) - if where1["AND"] != nil { - and := where1.GetMap("AND") - and[k] = v1.GetString("value") - } else { - where1[k] = v1.GetString("value") - where1 = Map{"AND": where1} - } - v1["count"] = that.Db.Count(tableName, where1) - ops[k1] = v1 - } - redData[k] = ops - } - - //检索查询 - if v.GetString("type") == "number" { - - if strings.Contains(k, "area_id") { - areas := that.Db.Select("area", "id,name", Map{"parent_id": 533301}) - for ak, av := range areas { - where1 := DeepCopyMap(where).(Map) - if where1["AND"] != nil { - and := where1.GetMap("AND") - and["area_id"] = av.GetCeilInt64("id") - } else { - where1["area_id"] = av.GetCeilInt64("id") - where1 = Map{"AND": where1} - } - av["count"] = that.Db.Count(tableName, where1) - areas[ak] = av - } - - redData["area"] = areas - continue - } - - if strings.Contains(k, "_id") { - continue - } - if k == "id" { - continue - } - if strings.Contains(k, "percent") { - continue - } - if strings.Contains(k, "exp_") { - continue - } - if strings.Contains(k, "side") { - continue - } - if strings.Contains(k, "lat") { - continue - } - if strings.Contains(k, "lng") { - continue - } - if strings.Contains(k, "distance") { - continue - } - where1 := DeepCopyMap(where).(Map) - redData[k] = that.Db.Sum(tableName, k, where1) - - } - } + } + + // 第三步:area 分析用单次 Select + Go 侧统计替代原来逐 area Count 循环 + if hasAreaId { + areas := that.Db.Select("area", "id,name", Map{"parent_id": 533301}) + areaIdRows := that.Db.Select(tableName, "area_id", where) + areaCountMap := map[int64]int64{} + for _, row := range areaIdRows { + areaCountMap[row.GetCeilInt64("area_id")]++ + } + for ak, av := range areas { + av["count"] = areaCountMap[av.GetCeilInt64("id")] + areas[ak] = av + } + redData["area"] = areas + } that.Display(0, redData) diff --git a/code/makecode.go b/code/makecode.go index 7070886..3440e53 100644 --- a/code/makecode.go +++ b/code/makecode.go @@ -1307,7 +1307,9 @@ func (that *MakeCode) Search(table string, userData Map, data Map, req *http.Req } if len(reqValue) != 0 && reqValue[0] != "" { - data[searchItemName] = reqValue + if that.TableColumns[table][searchItemName] != nil { + data[searchItemName] = reqValue + } } }