[{"data":1,"prerenderedAt":3551},["ShallowReactive",2],{"content:\u002F2025\u002F09\u002Freport-export-optimization-from-offset-to-cursor-pagination":3,"surround:\u002F2025\u002F09\u002Freport-export-optimization-from-offset-to-cursor-pagination":3540},{"id":4,"title":5,"body":6,"categories":3517,"date":3519,"description":3520,"draft":3521,"extension":3522,"image":3523,"meta":3524,"navigation":225,"path":3526,"permalink":3523,"published":3523,"readingTime":3527,"recommend":3523,"references":3523,"seo":3532,"sitemap":3533,"stem":3534,"tags":3535,"type":3538,"updated":3519,"__hash__":3539},"content\u002Fposts\u002F2025\u002F09\u002Freport-export-optimization-from-offset-to-cursor-pagination.md","10万行报表导出优化实战：从 OFFSET 到游标分页",{"type":7,"value":8,"toc":3512},"minimark",[9,13,16,19,22,25,29,40,47,82,85,90,234,237,242,249,260,274,277,2488,2491,2658,2664,2677,3262,3265,3485,3488,3491,3508],[10,11,12],"p",{},"记录一次大数据报表的优化",[10,14,15],{},"因为业务需求，需要一次性导出10万条数据的excel报表",[10,17,18],{},"第一次，我使用的全表扫描，花费8秒从数据库获取完整数据，将excel返回前端花了32秒，🤣",[10,20,21],{},"我想着这样不行",[10,23,24],{},"并对数据进行分片查询，并发读，流式写入文件，分片查询变成7秒，写入服务器6秒，总共13秒",[26,27,28],"h2",{"id":28},"查看对应的慢查询日志",[30,31,37],"pre",{"className":32,"code":34,"language":35,"meta":36},[33],"language-text","2025\u002F09\u002F03 22:30:15 \u002Fcode\u002Fprogram\u002Fcloud-game\u002Fbzv2\u002Fkit\u002Fbzgorm\u002Fdb_read_paginate.go:44 SLOW SQL >= 1s\n[7465.336ms] [rows:10000] SELECT *,(CASE WHEN `channel_id_last`='NaN' THEN '0' ELSE `channel_id_last` END) AS `channel_id_last` FROM `member` WHERE `wx_nickname` LIKE '%%' AND `id`>0 ORDER BY `last_online_at` DESC,`id` DESC LIMIT 10000 OFFSET 90000\n\n2025\u002F09\u002F03 22:30:15 \u002Fcode\u002Fprogram\u002Fcloud-game\u002Fbzv2\u002Fkit\u002Fbzgorm\u002Fdb_read_paginate.go:44 SLOW SQL >= 1s\n[7780.825ms] [rows:10000] SELECT *,(CASE WHEN `channel_id_last`='NaN' THEN '0' ELSE `channel_id_last` END) AS `channel_id_last` FROM `member` WHERE `wx_nickname` LIKE '%%' AND `id`>0 ORDER BY `last_online_at` DESC,`id` DESC LIMIT 10000 OFFSET 80000\n\n","text","",[38,39,34],"code",{"__ignoreMap":36},[10,41,42,46],{},[43,44,45],"strong",{},"SQL 执行的总耗时","，包含以下几个部分：",[48,49,50,62,72],"ol",{},[51,52,53,56],"li",{},[43,54,55],{},"生成 SQL 的时间",[57,58,59],"ul",{},[51,60,61],{},"GORM 会把条件、结构体、查询参数转换成 SQL 字符串，这个过程涉及反射和结构体解析。",[51,63,64,67],{},[43,65,66],{},"实际发送到数据库并返回结果的时间",[57,68,69],{},[51,70,71],{},"这是主要耗时部分，包括网络通信、数据库解析、执行查询和返回结果。",[51,73,74,77],{},[43,75,76],{},"扫描结果到结构体的时间",[57,78,79],{},[51,80,81],{},"GORM 会把数据库返回的行扫描到 Go 结构体里，这里也可能会消耗一些时间，尤其是大结果集和复杂结构体。",[26,83,84],{"id":84},"优化查询",[48,86,87],{},[51,88,89],{},"只返回特定的字段",[30,91,95],{"className":92,"code":93,"language":94,"meta":36,"style":36},"language-bash shiki shiki-themes github-light github-dark","2025\u002F09\u002F04 00:06:13 \u002Fcode\u002Fprogram\u002Fcloud-game\u002Fbzv2\u002Fkit\u002Fbzgorm\u002Fdb_read_paginate.go:44 SLOW SQL >= 1s\n[1952.019ms] [rows:10000] SELECT long_id,wx_nickname,created_at,last_online_at,address_last,user_agent_last,vip,pay_count,coin,score,agent_id,promoter_id FROM `member` WHERE `wx_nickname` LIKE '%%' AND `id`>0 ORDER BY `id` DESC LIMIT 10000 OFFSET 90000\n\n# 省略...\n","bash",[38,96,97,132,220,227],{"__ignoreMap":36},[98,99,102,106,110,113,116,119,123,126,129],"span",{"class":100,"data-line":101,"line":101},"line",1,[98,103,105],{"class":104},"sScJk","2025\u002F09\u002F04",[98,107,109],{"class":108},"sZZnC"," 00:06:13",[98,111,112],{"class":108}," \u002Fcode\u002Fprogram\u002Fcloud-game\u002Fbzv2\u002Fkit\u002Fbzgorm\u002Fdb_read_paginate.go:44",[98,114,115],{"class":108}," SLOW",[98,117,118],{"class":108}," SQL",[98,120,122],{"class":121},"szBVR"," ",[98,124,125],{"class":121},">",[98,127,128],{"class":108},"=",[98,130,131],{"class":108}," 1s\n",[98,133,135,139,143,146,148,150,153,155,158,161,164,166,169,172,175,177,180,183,186,188,191,193,195,198,200,202,204,207,210,214,217],{"class":100,"data-line":134,"line":134},2,[98,136,138],{"class":137},"sSDpw","[",[98,140,142],{"class":141},"sVt8B","1952.019ms",[98,144,145],{"class":137},"]",[98,147,122],{"class":141},[98,149,138],{"class":137},[98,151,152],{"class":141},"rows:10000",[98,154,145],{"class":137},[98,156,157],{"class":141}," SELECT long_id,wx_nickname,created_at,last_online_at,address_last,user_agent_last,vip,pay_count,coin,score,agent_id,promoter_id FROM ",[98,159,160],{"class":108},"`",[98,162,163],{"class":104},"member",[98,165,160],{"class":108},[98,167,168],{"class":104}," WHERE",[98,170,171],{"class":108}," `",[98,173,174],{"class":104},"wx_nickname",[98,176,160],{"class":108},[98,178,179],{"class":104}," LIKE",[98,181,182],{"class":108}," '%%'",[98,184,185],{"class":108}," AND",[98,187,171],{"class":108},[98,189,190],{"class":104},"id",[98,192,160],{"class":108},[98,194,125],{"class":121},[98,196,197],{"class":141},"0 ORDER BY ",[98,199,160],{"class":108},[98,201,190],{"class":104},[98,203,160],{"class":108},[98,205,206],{"class":104}," DESC",[98,208,209],{"class":108}," LIMIT",[98,211,213],{"class":212},"sj4cs"," 10000",[98,215,216],{"class":108}," OFFSET",[98,218,219],{"class":212}," 90000\n",[98,221,223],{"class":100,"data-line":222,"line":222},3,[98,224,226],{"emptyLinePlaceholder":225},true,"\n",[98,228,230],{"class":100,"data-line":229,"line":229},4,[98,231,233],{"class":232},"sJ8bj","# 省略...\n",[10,235,236],{},"明显快了很多",[48,238,239],{"start":134},[51,240,241],{},"简化查询逻辑",[10,243,244,245,248],{},"在代码逻辑上消除恒真匹配",[38,246,247],{"code":247},"%%","，也快了0.1s",[10,250,251,252,255,256,259],{},"如果你是 ",[43,253,254],{},"MySQL 8.x","，两种写法性能差别不大，推荐用 ",[43,257,258],{},"JOIN","，因为优化器对它的处理更可控。",[10,261,262,263,266,267,269,270,273],{},"如果是 ",[43,264,265],{},"MySQL 5.7 或更老版本","，强烈建议用 ",[43,268,258],{},"，因为 ",[38,271,272],{"code":272},"IN (子查询)"," 很容易被执行成“外层逐条匹配内层”。",[10,275,276],{},"经过优化后我把程序修改了一下",[30,278,282],{"className":279,"code":280,"language":281,"meta":36,"style":36},"language-go shiki shiki-themes github-light github-dark","\u002F\u002F MemberListExport 会员列表导出\nfunc (s *LpjService) MemberListExport(c *gin.Context, param *MemberListDto) {\n\tuser, ok := repository.Jwt.GetJwtData(c)\n\tif !ok || user == nil {\n\t\tbzgin.BadRequestResponse(c, \"用户信息异常\")\n\t\treturn\n\t}\n\n\tfilterFunc := s.memberListFilterFunc(param)\n\n\t\u002F\u002F 会员汇总信息\n\tmemberSummary, err := s.memberDomain.GetMemberSummary(func(tx *gorm.DB) *gorm.DB {\n\t\ttx = s.memberListSearchFilterFunc(param)(tx)\n\t\treturn tx.Unscoped().Scopes(filterFunc, s.sysUserMemberFilter(user)).Order(\"`id` DESC\")\n\t})\n\n\tif err != nil {\n\t\tbzgin.ErrorResponse(c, \"获取会员汇总信息失败\", err.Error())\n\t}\n\n\t\u002F\u002F 流式对象初始化\n\tfile := excelize.NewFile()\n\tsw, err := file.NewStreamWriter(\"Sheet1\")\n\tif err != nil {\n\t\tbzgin.ErrorResponse(c, \"创建流对象失败\")\n\t}\n\tcolNames := []any{\"ID\", \"昵称\", \"注册时间\", \"最后登录时间\", \"地域\", \"设备端\", \"VIP级别\", \"总充值\", \"金币数\", \"积分数\", \"代理ID\", \"代理昵称\", \"推广员ID\", \"推广员昵称\"}\n\tsw.SetRow(\"A1\", colNames)\n\n\t\u002F\u002F 并发任务\n\ttype memberChunk struct {\n\t\trowData [][]any\n\t\tpage    int\n\t}\n\tchunkSize := 10000                                                   \u002F\u002F 数据块大小\n\tchunkCount := (int(memberSummary.Count) + chunkSize - 1) \u002F chunkSize \u002F\u002F 数据块个数\n\tmemberCh := make(chan memberChunk, chunkCount)\n\n\tvar wg sync.WaitGroup\n\twg.Add(chunkCount)\n\t\u002F\u002F 生产者\n\tfor i := 0; i \u003C chunkCount; i++ {\n\t\tgo func(currentPage int) {\n\t\t\tdefer wg.Done()\n\t\t\tlist, _ := s.memberDomain.GetMembersWithLastPayTimeInPaginate(func(tx *gorm.DB) *gorm.DB {\n\t\t\t\ttx = tx.Debug()\n\t\t\t\ttx = s.memberListSearchFilterFunc(param)(tx)\n\t\t\t\ttx = tx.Unscoped().\n\t\t\t\t\tSelect(\"long_id,wx_nickname,created_at,last_online_at,address_last,user_agent_last,vip,pay_count,coin,score,agent_id,promoter_id\").\n\t\t\t\t\tScopes(filterFunc, s.sysUserMemberFilter(user))\n\t\t\t\treturn tx.Order(\"`id` DESC\")\n\t\t\t}, currentPage, chunkSize)\n\t\t\tdata := list.Data.([]*model.MemberWithIDNumberAndAgentPromoter)\n\t\t\tfmt.Println(\"len(data)\", len(data))\n\t\t\tstartRow := int64(2 + currentPage*chunkSize) \u002F\u002F 每个分页对应 Excel 的起始行\n\t\t\tfmt.Println(\"startRow\", startRow)\n\n\t\t\trowData := make([][]any, len(data))\n\t\t\tfor idx, m := range data {\n\t\t\t\trow := []any{\n\t\t\t\t\tm.LongId,     \u002F\u002F ID\n\t\t\t\t\tm.WxNickname, \u002F\u002F 昵称\n\t\t\t\t\tm.CreatedAt.Format(\"2006-01-02 15:04:05\"),    \u002F\u002F 注册时间\n\t\t\t\t\tm.LastOnlineAt.Format(\"2006-01-02 15:04:05\"), \u002F\u002F 最后登录时间\n\t\t\t\t\tm.AddressLast,         \u002F\u002F 地域\n\t\t\t\t\tm.UserAgentLast,       \u002F\u002F 设备端\n\t\t\t\t\tm.Vip,                 \u002F\u002F VIP级别\n\t\t\t\t\tm.PayCount,            \u002F\u002F 总充值\n\t\t\t\t\tm.Coin,                \u002F\u002F 金币数\n\t\t\t\t\tm.Score,               \u002F\u002F 积分数\n\t\t\t\t\tm.AgentId,             \u002F\u002F 代理ID\n\t\t\t\t\tm.Agent.WxNickname,    \u002F\u002F 代理昵称\n\t\t\t\t\tm.PromoterId,          \u002F\u002F 推广员ID\n\t\t\t\t\tm.Promoter.WxNickname, \u002F\u002F 推广员昵称\n\t\t\t\t}\n\t\t\t\trowData[idx] = row\n\t\t\t}\n\t\t\tmemberCh \u003C- memberChunk{rowData: rowData, page: currentPage}\n\t\t}(i)\n\t}\n\n\twg.Wait()\n\tclose(memberCh)\n\n\t\u002F\u002F 消费者, 并发写Excel不安全，放在主goroutine串行处理\n\tfor mc := range memberCh {\n\t\trowStart := 2 + mc.page*chunkSize\n\t\tfor idx, row := range mc.rowData {\n\t\t\tsw.SetRow(fmt.Sprintf(\"A%d\", rowStart+idx), row)\n\t\t}\n\t}\n\t\u002F\u002F 将缓冲写入excel\n\tif err := sw.Flush(); err != nil {\n\t\tbzgin.ErrorResponse(c, \"缓冲写入excel失败\", err.Error())\n\t}\n\n\t\u002F\u002F 设置响应头，提示浏览器下载\n\tc.Header(\"Content-Type\", \"application\u002Fvnd.openxmlformats-officedocument.spreadsheetml.sheet\")\n\tc.Header(\"Content-Disposition\", \"attachment; filename=report.xlsx\")\n\tc.Header(\"Content-Transfer-Encoding\", \"binary\")\n\n\t\u002F\u002F 把 Excel 内容写入响应\n\tif err := file.Write(c.Writer); err != nil {\n\t\tbzgin.ErrorResponse(c, \"导出失败\", err.Error())\n\t\treturn\n\t}\n}\n","go",[38,283,284,289,352,378,407,431,441,451,456,478,483,491,542,571,625,637,642,661,692,701,706,714,734,757,774,794,803,895,916,921,929,947,968,981,990,1005,1055,1080,1085,1104,1122,1130,1162,1188,1210,1261,1285,1316,1342,1367,1396,1419,1437,1472,1506,1546,1569,1574,1613,1637,1663,1682,1701,1733,1762,1781,1800,1819,1838,1857,1876,1895,1914,1933,1952,1967,1995,2008,2032,2050,2059,2064,2078,2093,2098,2106,2125,2150,2171,2216,2227,2236,2244,2276,2304,2313,2318,2326,2349,2370,2391,2396,2404,2437,2465,2474,2483],{"__ignoreMap":36},[98,285,286],{"class":100,"data-line":101,"line":101},[98,287,288],{"class":232},"\u002F\u002F MemberListExport 会员列表导出\n",[98,290,291,294,296,299,303,306,309,312,314,317,319,322,325,328,331,334,337,340,342,345,347,349],{"class":100,"data-line":134,"line":134},[98,292,293],{"class":121},"func",[98,295,122],{"class":141},[98,297,298],{"class":137},"(",[98,300,302],{"class":301},"s4XuR","s ",[98,304,305],{"class":121},"*",[98,307,308],{"class":104},"LpjService",[98,310,311],{"class":137},")",[98,313,122],{"class":141},[98,315,316],{"class":104},"MemberListExport",[98,318,298],{"class":137},[98,320,321],{"class":301},"c",[98,323,324],{"class":121}," *",[98,326,327],{"class":104},"gin",[98,329,330],{"class":141},".",[98,332,333],{"class":104},"Context",[98,335,336],{"class":141},", ",[98,338,339],{"class":301},"param",[98,341,324],{"class":121},[98,343,344],{"class":104},"MemberListDto",[98,346,311],{"class":137},[98,348,122],{"class":141},[98,350,351],{"class":137},"{\n",[98,353,354,358,361,364,367,370,373,375],{"class":100,"data-line":222,"line":222},[98,355,357],{"class":356},"indent","\t",[98,359,360],{"class":141},"user, ok ",[98,362,363],{"class":121},":=",[98,365,366],{"class":141}," repository.Jwt.",[98,368,369],{"class":104},"GetJwtData",[98,371,298],{"class":372},"sJX2D",[98,374,321],{"class":141},[98,376,377],{"class":372},")\n",[98,379,380,382,385,388,391,394,397,400,403,405],{"class":100,"data-line":229,"line":229},[98,381,357],{"class":356},[98,383,384],{"class":121},"if",[98,386,387],{"class":121}," !",[98,389,390],{"class":141},"ok ",[98,392,393],{"class":121},"||",[98,395,396],{"class":141}," user ",[98,398,399],{"class":121},"==",[98,401,402],{"class":212}," nil",[98,404,122],{"class":141},[98,406,351],{"class":372},[98,408,410,412,414,417,420,423,426,429],{"class":100,"data-line":409,"line":409},5,[98,411,357],{"class":356},[98,413,357],{"class":356},[98,415,416],{"class":141},"bzgin.",[98,418,419],{"class":104},"BadRequestResponse",[98,421,298],{"class":422},"sqkie",[98,424,425],{"class":141},"c, ",[98,427,428],{"class":108},"\"用户信息异常\"",[98,430,377],{"class":422},[98,432,434,436,438],{"class":100,"data-line":433,"line":433},6,[98,435,357],{"class":356},[98,437,357],{"class":356},[98,439,440],{"class":121},"return\n",[98,442,444,446,448],{"class":100,"data-line":443,"line":443},7,[98,445,357],{"class":356},[98,447,36],{"class":141},[98,449,450],{"class":372},"}\n",[98,452,454],{"class":100,"data-line":453,"line":453},8,[98,455,226],{"emptyLinePlaceholder":225},[98,457,459,461,464,466,469,472,474,476],{"class":100,"data-line":458,"line":458},9,[98,460,357],{"class":356},[98,462,463],{"class":141},"filterFunc ",[98,465,363],{"class":121},[98,467,468],{"class":141}," s.",[98,470,471],{"class":104},"memberListFilterFunc",[98,473,298],{"class":372},[98,475,339],{"class":141},[98,477,377],{"class":372},[98,479,481],{"class":100,"data-line":480,"line":480},10,[98,482,226],{"emptyLinePlaceholder":225},[98,484,486,488],{"class":100,"data-line":485,"line":485},11,[98,487,357],{"class":356},[98,489,490],{"class":232},"\u002F\u002F 会员汇总信息\n",[98,492,494,496,499,501,504,507,509,511,513,516,518,521,523,526,528,530,532,534,536,538,540],{"class":100,"data-line":493,"line":493},12,[98,495,357],{"class":356},[98,497,498],{"class":141},"memberSummary, err ",[98,500,363],{"class":121},[98,502,503],{"class":141}," s.memberDomain.",[98,505,506],{"class":104},"GetMemberSummary",[98,508,298],{"class":372},[98,510,293],{"class":121},[98,512,298],{"class":422},[98,514,515],{"class":301},"tx",[98,517,324],{"class":121},[98,519,520],{"class":104},"gorm",[98,522,330],{"class":141},[98,524,525],{"class":104},"DB",[98,527,311],{"class":422},[98,529,122],{"class":141},[98,531,305],{"class":121},[98,533,520],{"class":104},[98,535,330],{"class":141},[98,537,525],{"class":104},[98,539,122],{"class":141},[98,541,351],{"class":422},[98,543,545,547,549,552,554,556,559,561,563,565,567,569],{"class":100,"data-line":544,"line":544},13,[98,546,357],{"class":356},[98,548,357],{"class":356},[98,550,551],{"class":141},"tx ",[98,553,128],{"class":121},[98,555,468],{"class":141},[98,557,558],{"class":104},"memberListSearchFilterFunc",[98,560,298],{"class":137},[98,562,339],{"class":141},[98,564,311],{"class":137},[98,566,298],{"class":137},[98,568,515],{"class":141},[98,570,377],{"class":137},[98,572,574,576,578,581,584,587,589,591,593,596,598,601,604,606,609,611,613,615,618,620,623],{"class":100,"data-line":573,"line":573},14,[98,575,357],{"class":356},[98,577,357],{"class":356},[98,579,580],{"class":121},"return",[98,582,583],{"class":141}," tx.",[98,585,586],{"class":104},"Unscoped",[98,588,298],{"class":137},[98,590,311],{"class":137},[98,592,330],{"class":141},[98,594,595],{"class":104},"Scopes",[98,597,298],{"class":137},[98,599,600],{"class":141},"filterFunc, s.",[98,602,603],{"class":104},"sysUserMemberFilter",[98,605,298],{"class":372},[98,607,608],{"class":141},"user",[98,610,311],{"class":372},[98,612,311],{"class":137},[98,614,330],{"class":141},[98,616,617],{"class":104},"Order",[98,619,298],{"class":137},[98,621,622],{"class":108},"\"`id` DESC\"",[98,624,377],{"class":137},[98,626,628,630,632,635],{"class":100,"data-line":627,"line":627},15,[98,629,357],{"class":356},[98,631,36],{"class":141},[98,633,634],{"class":422},"}",[98,636,377],{"class":372},[98,638,640],{"class":100,"data-line":639,"line":639},16,[98,641,226],{"emptyLinePlaceholder":225},[98,643,645,647,649,652,655,657,659],{"class":100,"data-line":644,"line":644},17,[98,646,357],{"class":356},[98,648,384],{"class":121},[98,650,651],{"class":141}," err ",[98,653,654],{"class":121},"!=",[98,656,402],{"class":212},[98,658,122],{"class":141},[98,660,351],{"class":372},[98,662,664,666,668,670,673,675,677,680,683,686,688,690],{"class":100,"data-line":663,"line":663},18,[98,665,357],{"class":356},[98,667,357],{"class":356},[98,669,416],{"class":141},[98,671,672],{"class":104},"ErrorResponse",[98,674,298],{"class":422},[98,676,425],{"class":141},[98,678,679],{"class":108},"\"获取会员汇总信息失败\"",[98,681,682],{"class":141},", err.",[98,684,685],{"class":104},"Error",[98,687,298],{"class":137},[98,689,311],{"class":137},[98,691,377],{"class":422},[98,693,695,697,699],{"class":100,"data-line":694,"line":694},19,[98,696,357],{"class":356},[98,698,36],{"class":141},[98,700,450],{"class":372},[98,702,704],{"class":100,"data-line":703,"line":703},20,[98,705,226],{"emptyLinePlaceholder":225},[98,707,709,711],{"class":100,"data-line":708,"line":708},21,[98,710,357],{"class":356},[98,712,713],{"class":232},"\u002F\u002F 流式对象初始化\n",[98,715,717,719,722,724,727,730,732],{"class":100,"data-line":716,"line":716},22,[98,718,357],{"class":356},[98,720,721],{"class":141},"file ",[98,723,363],{"class":121},[98,725,726],{"class":141}," excelize.",[98,728,729],{"class":104},"NewFile",[98,731,298],{"class":372},[98,733,377],{"class":372},[98,735,737,739,742,744,747,750,752,755],{"class":100,"data-line":736,"line":736},23,[98,738,357],{"class":356},[98,740,741],{"class":141},"sw, err ",[98,743,363],{"class":121},[98,745,746],{"class":141}," file.",[98,748,749],{"class":104},"NewStreamWriter",[98,751,298],{"class":372},[98,753,754],{"class":108},"\"Sheet1\"",[98,756,377],{"class":372},[98,758,760,762,764,766,768,770,772],{"class":100,"data-line":759,"line":759},24,[98,761,357],{"class":356},[98,763,384],{"class":121},[98,765,651],{"class":141},[98,767,654],{"class":121},[98,769,402],{"class":212},[98,771,122],{"class":141},[98,773,351],{"class":372},[98,775,777,779,781,783,785,787,789,792],{"class":100,"data-line":776,"line":776},25,[98,778,357],{"class":356},[98,780,357],{"class":356},[98,782,416],{"class":141},[98,784,672],{"class":104},[98,786,298],{"class":422},[98,788,425],{"class":141},[98,790,791],{"class":108},"\"创建流对象失败\"",[98,793,377],{"class":422},[98,795,797,799,801],{"class":100,"data-line":796,"line":796},26,[98,798,357],{"class":356},[98,800,36],{"class":141},[98,802,450],{"class":372},[98,804,806,808,811,813,815,817,819,822,825,828,830,833,835,838,840,843,845,848,850,853,855,858,860,863,865,868,870,873,875,878,880,883,885,888,890,893],{"class":100,"data-line":805,"line":805},27,[98,807,357],{"class":356},[98,809,810],{"class":141},"colNames ",[98,812,363],{"class":121},[98,814,122],{"class":141},[98,816,138],{"class":372},[98,818,145],{"class":372},[98,820,821],{"class":104},"any",[98,823,824],{"class":372},"{",[98,826,827],{"class":108},"\"ID\"",[98,829,336],{"class":141},[98,831,832],{"class":108},"\"昵称\"",[98,834,336],{"class":141},[98,836,837],{"class":108},"\"注册时间\"",[98,839,336],{"class":141},[98,841,842],{"class":108},"\"最后登录时间\"",[98,844,336],{"class":141},[98,846,847],{"class":108},"\"地域\"",[98,849,336],{"class":141},[98,851,852],{"class":108},"\"设备端\"",[98,854,336],{"class":141},[98,856,857],{"class":108},"\"VIP级别\"",[98,859,336],{"class":141},[98,861,862],{"class":108},"\"总充值\"",[98,864,336],{"class":141},[98,866,867],{"class":108},"\"金币数\"",[98,869,336],{"class":141},[98,871,872],{"class":108},"\"积分数\"",[98,874,336],{"class":141},[98,876,877],{"class":108},"\"代理ID\"",[98,879,336],{"class":141},[98,881,882],{"class":108},"\"代理昵称\"",[98,884,336],{"class":141},[98,886,887],{"class":108},"\"推广员ID\"",[98,889,336],{"class":141},[98,891,892],{"class":108},"\"推广员昵称\"",[98,894,450],{"class":372},[98,896,898,900,903,906,908,911,914],{"class":100,"data-line":897,"line":897},28,[98,899,357],{"class":356},[98,901,902],{"class":141},"sw.",[98,904,905],{"class":104},"SetRow",[98,907,298],{"class":372},[98,909,910],{"class":108},"\"A1\"",[98,912,913],{"class":141},", colNames",[98,915,377],{"class":372},[98,917,919],{"class":100,"data-line":918,"line":918},29,[98,920,226],{"emptyLinePlaceholder":225},[98,922,924,926],{"class":100,"data-line":923,"line":923},30,[98,925,357],{"class":356},[98,927,928],{"class":232},"\u002F\u002F 并发任务\n",[98,930,932,934,937,940,943,945],{"class":100,"data-line":931,"line":931},31,[98,933,357],{"class":356},[98,935,936],{"class":121},"type",[98,938,939],{"class":104}," memberChunk",[98,941,942],{"class":121}," struct",[98,944,122],{"class":141},[98,946,351],{"class":372},[98,948,950,952,954,957,959,961,963,965],{"class":100,"data-line":949,"line":949},32,[98,951,357],{"class":356},[98,953,357],{"class":356},[98,955,956],{"class":141},"rowData ",[98,958,138],{"class":422},[98,960,145],{"class":422},[98,962,138],{"class":422},[98,964,145],{"class":422},[98,966,967],{"class":104},"any\n",[98,969,971,973,975,978],{"class":100,"data-line":970,"line":970},33,[98,972,357],{"class":356},[98,974,357],{"class":356},[98,976,977],{"class":141},"page    ",[98,979,980],{"class":121},"int\n",[98,982,984,986,988],{"class":100,"data-line":983,"line":983},34,[98,985,357],{"class":356},[98,987,36],{"class":141},[98,989,450],{"class":372},[98,991,993,995,998,1000,1002],{"class":100,"data-line":992,"line":992},35,[98,994,357],{"class":356},[98,996,997],{"class":141},"chunkSize ",[98,999,363],{"class":121},[98,1001,213],{"class":212},[98,1003,1004],{"class":232},"                                                   \u002F\u002F 数据块大小\n",[98,1006,1008,1010,1013,1015,1017,1019,1022,1024,1027,1029,1031,1034,1037,1040,1043,1045,1047,1050,1052],{"class":100,"data-line":1007,"line":1007},36,[98,1009,357],{"class":356},[98,1011,1012],{"class":141},"chunkCount ",[98,1014,363],{"class":121},[98,1016,122],{"class":141},[98,1018,298],{"class":372},[98,1020,1021],{"class":121},"int",[98,1023,298],{"class":422},[98,1025,1026],{"class":141},"memberSummary.Count",[98,1028,311],{"class":422},[98,1030,122],{"class":141},[98,1032,1033],{"class":121},"+",[98,1035,1036],{"class":141}," chunkSize ",[98,1038,1039],{"class":121},"-",[98,1041,1042],{"class":212}," 1",[98,1044,311],{"class":372},[98,1046,122],{"class":141},[98,1048,1049],{"class":121},"\u002F",[98,1051,1036],{"class":141},[98,1053,1054],{"class":232},"\u002F\u002F 数据块个数\n",[98,1056,1058,1060,1063,1065,1068,1070,1073,1075,1078],{"class":100,"data-line":1057,"line":1057},37,[98,1059,357],{"class":356},[98,1061,1062],{"class":141},"memberCh ",[98,1064,363],{"class":121},[98,1066,1067],{"class":104}," make",[98,1069,298],{"class":372},[98,1071,1072],{"class":121},"chan",[98,1074,939],{"class":104},[98,1076,1077],{"class":141},", chunkCount",[98,1079,377],{"class":372},[98,1081,1083],{"class":100,"data-line":1082,"line":1082},38,[98,1084,226],{"emptyLinePlaceholder":225},[98,1086,1088,1090,1093,1096,1099,1101],{"class":100,"data-line":1087,"line":1087},39,[98,1089,357],{"class":356},[98,1091,1092],{"class":121},"var",[98,1094,1095],{"class":141}," wg ",[98,1097,1098],{"class":104},"sync",[98,1100,330],{"class":141},[98,1102,1103],{"class":104},"WaitGroup\n",[98,1105,1107,1109,1112,1115,1117,1120],{"class":100,"data-line":1106,"line":1106},40,[98,1108,357],{"class":356},[98,1110,1111],{"class":141},"wg.",[98,1113,1114],{"class":104},"Add",[98,1116,298],{"class":372},[98,1118,1119],{"class":141},"chunkCount",[98,1121,377],{"class":372},[98,1123,1125,1127],{"class":100,"data-line":1124,"line":1124},41,[98,1126,357],{"class":356},[98,1128,1129],{"class":232},"\u002F\u002F 生产者\n",[98,1131,1133,1135,1138,1141,1143,1146,1149,1152,1155,1158,1160],{"class":100,"data-line":1132,"line":1132},42,[98,1134,357],{"class":356},[98,1136,1137],{"class":121},"for",[98,1139,1140],{"class":141}," i ",[98,1142,363],{"class":121},[98,1144,1145],{"class":212}," 0",[98,1147,1148],{"class":141},"; i ",[98,1150,1151],{"class":121},"\u003C",[98,1153,1154],{"class":141}," chunkCount; i",[98,1156,1157],{"class":121},"++",[98,1159,122],{"class":141},[98,1161,351],{"class":372},[98,1163,1165,1167,1169,1171,1174,1176,1179,1182,1184,1186],{"class":100,"data-line":1164,"line":1164},43,[98,1166,357],{"class":356},[98,1168,357],{"class":356},[98,1170,281],{"class":121},[98,1172,1173],{"class":121}," func",[98,1175,298],{"class":422},[98,1177,1178],{"class":301},"currentPage",[98,1180,1181],{"class":121}," int",[98,1183,311],{"class":422},[98,1185,122],{"class":141},[98,1187,351],{"class":422},[98,1189,1191,1193,1195,1197,1200,1203,1206,1208],{"class":100,"data-line":1190,"line":1190},44,[98,1192,357],{"class":356},[98,1194,357],{"class":356},[98,1196,357],{"class":356},[98,1198,1199],{"class":121},"defer",[98,1201,1202],{"class":141}," wg.",[98,1204,1205],{"class":104},"Done",[98,1207,298],{"class":137},[98,1209,377],{"class":137},[98,1211,1213,1215,1217,1219,1222,1224,1226,1229,1231,1233,1235,1237,1239,1241,1243,1245,1247,1249,1251,1253,1255,1257,1259],{"class":100,"data-line":1212,"line":1212},45,[98,1214,357],{"class":356},[98,1216,357],{"class":356},[98,1218,357],{"class":356},[98,1220,1221],{"class":141},"list, _ ",[98,1223,363],{"class":121},[98,1225,503],{"class":141},[98,1227,1228],{"class":104},"GetMembersWithLastPayTimeInPaginate",[98,1230,298],{"class":137},[98,1232,293],{"class":121},[98,1234,298],{"class":372},[98,1236,515],{"class":301},[98,1238,324],{"class":121},[98,1240,520],{"class":104},[98,1242,330],{"class":141},[98,1244,525],{"class":104},[98,1246,311],{"class":372},[98,1248,122],{"class":141},[98,1250,305],{"class":121},[98,1252,520],{"class":104},[98,1254,330],{"class":141},[98,1256,525],{"class":104},[98,1258,122],{"class":141},[98,1260,351],{"class":372},[98,1262,1264,1266,1268,1270,1272,1274,1276,1278,1281,1283],{"class":100,"data-line":1263,"line":1263},46,[98,1265,357],{"class":356},[98,1267,357],{"class":356},[98,1269,357],{"class":356},[98,1271,357],{"class":356},[98,1273,551],{"class":141},[98,1275,128],{"class":121},[98,1277,583],{"class":141},[98,1279,1280],{"class":104},"Debug",[98,1282,298],{"class":422},[98,1284,377],{"class":422},[98,1286,1288,1290,1292,1294,1296,1298,1300,1302,1304,1306,1308,1310,1312,1314],{"class":100,"data-line":1287,"line":1287},47,[98,1289,357],{"class":356},[98,1291,357],{"class":356},[98,1293,357],{"class":356},[98,1295,357],{"class":356},[98,1297,551],{"class":141},[98,1299,128],{"class":121},[98,1301,468],{"class":141},[98,1303,558],{"class":104},[98,1305,298],{"class":422},[98,1307,339],{"class":141},[98,1309,311],{"class":422},[98,1311,298],{"class":422},[98,1313,515],{"class":141},[98,1315,377],{"class":422},[98,1317,1319,1321,1323,1325,1327,1329,1331,1333,1335,1337,1339],{"class":100,"data-line":1318,"line":1318},48,[98,1320,357],{"class":356},[98,1322,357],{"class":356},[98,1324,357],{"class":356},[98,1326,357],{"class":356},[98,1328,551],{"class":141},[98,1330,128],{"class":121},[98,1332,583],{"class":141},[98,1334,586],{"class":104},[98,1336,298],{"class":422},[98,1338,311],{"class":422},[98,1340,1341],{"class":141},".\n",[98,1343,1345,1347,1349,1351,1353,1355,1358,1360,1363,1365],{"class":100,"data-line":1344,"line":1344},49,[98,1346,357],{"class":356},[98,1348,357],{"class":356},[98,1350,357],{"class":356},[98,1352,357],{"class":356},[98,1354,357],{"class":356},[98,1356,1357],{"class":104},"Select",[98,1359,298],{"class":422},[98,1361,1362],{"class":108},"\"long_id,wx_nickname,created_at,last_online_at,address_last,user_agent_last,vip,pay_count,coin,score,agent_id,promoter_id\"",[98,1364,311],{"class":422},[98,1366,1341],{"class":141},[98,1368,1370,1372,1374,1376,1378,1380,1382,1384,1386,1388,1390,1392,1394],{"class":100,"data-line":1369,"line":1369},50,[98,1371,357],{"class":356},[98,1373,357],{"class":356},[98,1375,357],{"class":356},[98,1377,357],{"class":356},[98,1379,357],{"class":356},[98,1381,595],{"class":104},[98,1383,298],{"class":422},[98,1385,600],{"class":141},[98,1387,603],{"class":104},[98,1389,298],{"class":137},[98,1391,608],{"class":141},[98,1393,311],{"class":137},[98,1395,377],{"class":422},[98,1397,1399,1401,1403,1405,1407,1409,1411,1413,1415,1417],{"class":100,"data-line":1398,"line":1398},51,[98,1400,357],{"class":356},[98,1402,357],{"class":356},[98,1404,357],{"class":356},[98,1406,357],{"class":356},[98,1408,580],{"class":121},[98,1410,583],{"class":141},[98,1412,617],{"class":104},[98,1414,298],{"class":422},[98,1416,622],{"class":108},[98,1418,377],{"class":422},[98,1420,1422,1424,1426,1428,1430,1432,1435],{"class":100,"data-line":1421,"line":1421},52,[98,1423,357],{"class":356},[98,1425,357],{"class":356},[98,1427,357],{"class":356},[98,1429,36],{"class":141},[98,1431,634],{"class":372},[98,1433,1434],{"class":141},", currentPage, chunkSize",[98,1436,377],{"class":137},[98,1438,1440,1442,1444,1446,1449,1451,1454,1456,1458,1460,1462,1465,1467,1470],{"class":100,"data-line":1439,"line":1439},53,[98,1441,357],{"class":356},[98,1443,357],{"class":356},[98,1445,357],{"class":356},[98,1447,1448],{"class":141},"data ",[98,1450,363],{"class":121},[98,1452,1453],{"class":141}," list.Data.",[98,1455,298],{"class":137},[98,1457,138],{"class":372},[98,1459,145],{"class":372},[98,1461,305],{"class":121},[98,1463,1464],{"class":104},"model",[98,1466,330],{"class":141},[98,1468,1469],{"class":104},"MemberWithIDNumberAndAgentPromoter",[98,1471,377],{"class":137},[98,1473,1475,1477,1479,1481,1484,1487,1489,1492,1494,1497,1499,1502,1504],{"class":100,"data-line":1474,"line":1474},54,[98,1476,357],{"class":356},[98,1478,357],{"class":356},[98,1480,357],{"class":356},[98,1482,1483],{"class":141},"fmt.",[98,1485,1486],{"class":104},"Println",[98,1488,298],{"class":137},[98,1490,1491],{"class":108},"\"len(data)\"",[98,1493,336],{"class":141},[98,1495,1496],{"class":104},"len",[98,1498,298],{"class":372},[98,1500,1501],{"class":141},"data",[98,1503,311],{"class":372},[98,1505,377],{"class":137},[98,1507,1509,1511,1513,1515,1518,1520,1523,1525,1528,1531,1534,1536,1539,1541,1543],{"class":100,"data-line":1508,"line":1508},55,[98,1510,357],{"class":356},[98,1512,357],{"class":356},[98,1514,357],{"class":356},[98,1516,1517],{"class":141},"startRow ",[98,1519,363],{"class":121},[98,1521,1522],{"class":121}," int64",[98,1524,298],{"class":137},[98,1526,1527],{"class":212},"2",[98,1529,1530],{"class":121}," +",[98,1532,1533],{"class":141}," currentPage",[98,1535,305],{"class":121},[98,1537,1538],{"class":141},"chunkSize",[98,1540,311],{"class":137},[98,1542,122],{"class":141},[98,1544,1545],{"class":232},"\u002F\u002F 每个分页对应 Excel 的起始行\n",[98,1547,1549,1551,1553,1555,1557,1559,1561,1564,1567],{"class":100,"data-line":1548,"line":1548},56,[98,1550,357],{"class":356},[98,1552,357],{"class":356},[98,1554,357],{"class":356},[98,1556,1483],{"class":141},[98,1558,1486],{"class":104},[98,1560,298],{"class":137},[98,1562,1563],{"class":108},"\"startRow\"",[98,1565,1566],{"class":141},", startRow",[98,1568,377],{"class":137},[98,1570,1572],{"class":100,"data-line":1571,"line":1571},57,[98,1573,226],{"emptyLinePlaceholder":225},[98,1575,1577,1579,1581,1583,1585,1587,1589,1591,1593,1595,1597,1599,1601,1603,1605,1607,1609,1611],{"class":100,"data-line":1576,"line":1576},58,[98,1578,357],{"class":356},[98,1580,357],{"class":356},[98,1582,357],{"class":356},[98,1584,956],{"class":141},[98,1586,363],{"class":121},[98,1588,1067],{"class":104},[98,1590,298],{"class":137},[98,1592,138],{"class":372},[98,1594,145],{"class":372},[98,1596,138],{"class":372},[98,1598,145],{"class":372},[98,1600,821],{"class":104},[98,1602,336],{"class":141},[98,1604,1496],{"class":104},[98,1606,298],{"class":372},[98,1608,1501],{"class":141},[98,1610,311],{"class":372},[98,1612,377],{"class":137},[98,1614,1616,1618,1620,1622,1624,1627,1629,1632,1635],{"class":100,"data-line":1615,"line":1615},59,[98,1617,357],{"class":356},[98,1619,357],{"class":356},[98,1621,357],{"class":356},[98,1623,1137],{"class":121},[98,1625,1626],{"class":141}," idx, m ",[98,1628,363],{"class":121},[98,1630,1631],{"class":121}," range",[98,1633,1634],{"class":141}," data ",[98,1636,351],{"class":137},[98,1638,1640,1642,1644,1646,1648,1651,1653,1655,1657,1659,1661],{"class":100,"data-line":1639,"line":1639},60,[98,1641,357],{"class":356},[98,1643,357],{"class":356},[98,1645,357],{"class":356},[98,1647,357],{"class":356},[98,1649,1650],{"class":141},"row ",[98,1652,363],{"class":121},[98,1654,122],{"class":141},[98,1656,138],{"class":372},[98,1658,145],{"class":372},[98,1660,821],{"class":104},[98,1662,351],{"class":372},[98,1664,1666,1668,1670,1672,1674,1676,1679],{"class":100,"data-line":1665,"line":1665},61,[98,1667,357],{"class":356},[98,1669,357],{"class":356},[98,1671,357],{"class":356},[98,1673,357],{"class":356},[98,1675,357],{"class":356},[98,1677,1678],{"class":141},"m.LongId,     ",[98,1680,1681],{"class":232},"\u002F\u002F ID\n",[98,1683,1685,1687,1689,1691,1693,1695,1698],{"class":100,"data-line":1684,"line":1684},62,[98,1686,357],{"class":356},[98,1688,357],{"class":356},[98,1690,357],{"class":356},[98,1692,357],{"class":356},[98,1694,357],{"class":356},[98,1696,1697],{"class":141},"m.WxNickname, ",[98,1699,1700],{"class":232},"\u002F\u002F 昵称\n",[98,1702,1704,1706,1708,1710,1712,1714,1717,1720,1722,1725,1727,1730],{"class":100,"data-line":1703,"line":1703},63,[98,1705,357],{"class":356},[98,1707,357],{"class":356},[98,1709,357],{"class":356},[98,1711,357],{"class":356},[98,1713,357],{"class":356},[98,1715,1716],{"class":141},"m.CreatedAt.",[98,1718,1719],{"class":104},"Format",[98,1721,298],{"class":422},[98,1723,1724],{"class":108},"\"2006-01-02 15:04:05\"",[98,1726,311],{"class":422},[98,1728,1729],{"class":141},",    ",[98,1731,1732],{"class":232},"\u002F\u002F 注册时间\n",[98,1734,1736,1738,1740,1742,1744,1746,1749,1751,1753,1755,1757,1759],{"class":100,"data-line":1735,"line":1735},64,[98,1737,357],{"class":356},[98,1739,357],{"class":356},[98,1741,357],{"class":356},[98,1743,357],{"class":356},[98,1745,357],{"class":356},[98,1747,1748],{"class":141},"m.LastOnlineAt.",[98,1750,1719],{"class":104},[98,1752,298],{"class":422},[98,1754,1724],{"class":108},[98,1756,311],{"class":422},[98,1758,336],{"class":141},[98,1760,1761],{"class":232},"\u002F\u002F 最后登录时间\n",[98,1763,1765,1767,1769,1771,1773,1775,1778],{"class":100,"data-line":1764,"line":1764},65,[98,1766,357],{"class":356},[98,1768,357],{"class":356},[98,1770,357],{"class":356},[98,1772,357],{"class":356},[98,1774,357],{"class":356},[98,1776,1777],{"class":141},"m.AddressLast,         ",[98,1779,1780],{"class":232},"\u002F\u002F 地域\n",[98,1782,1784,1786,1788,1790,1792,1794,1797],{"class":100,"data-line":1783,"line":1783},66,[98,1785,357],{"class":356},[98,1787,357],{"class":356},[98,1789,357],{"class":356},[98,1791,357],{"class":356},[98,1793,357],{"class":356},[98,1795,1796],{"class":141},"m.UserAgentLast,       ",[98,1798,1799],{"class":232},"\u002F\u002F 设备端\n",[98,1801,1803,1805,1807,1809,1811,1813,1816],{"class":100,"data-line":1802,"line":1802},67,[98,1804,357],{"class":356},[98,1806,357],{"class":356},[98,1808,357],{"class":356},[98,1810,357],{"class":356},[98,1812,357],{"class":356},[98,1814,1815],{"class":141},"m.Vip,                 ",[98,1817,1818],{"class":232},"\u002F\u002F VIP级别\n",[98,1820,1822,1824,1826,1828,1830,1832,1835],{"class":100,"data-line":1821,"line":1821},68,[98,1823,357],{"class":356},[98,1825,357],{"class":356},[98,1827,357],{"class":356},[98,1829,357],{"class":356},[98,1831,357],{"class":356},[98,1833,1834],{"class":141},"m.PayCount,            ",[98,1836,1837],{"class":232},"\u002F\u002F 总充值\n",[98,1839,1841,1843,1845,1847,1849,1851,1854],{"class":100,"data-line":1840,"line":1840},69,[98,1842,357],{"class":356},[98,1844,357],{"class":356},[98,1846,357],{"class":356},[98,1848,357],{"class":356},[98,1850,357],{"class":356},[98,1852,1853],{"class":141},"m.Coin,                ",[98,1855,1856],{"class":232},"\u002F\u002F 金币数\n",[98,1858,1860,1862,1864,1866,1868,1870,1873],{"class":100,"data-line":1859,"line":1859},70,[98,1861,357],{"class":356},[98,1863,357],{"class":356},[98,1865,357],{"class":356},[98,1867,357],{"class":356},[98,1869,357],{"class":356},[98,1871,1872],{"class":141},"m.Score,               ",[98,1874,1875],{"class":232},"\u002F\u002F 积分数\n",[98,1877,1879,1881,1883,1885,1887,1889,1892],{"class":100,"data-line":1878,"line":1878},71,[98,1880,357],{"class":356},[98,1882,357],{"class":356},[98,1884,357],{"class":356},[98,1886,357],{"class":356},[98,1888,357],{"class":356},[98,1890,1891],{"class":141},"m.AgentId,             ",[98,1893,1894],{"class":232},"\u002F\u002F 代理ID\n",[98,1896,1898,1900,1902,1904,1906,1908,1911],{"class":100,"data-line":1897,"line":1897},72,[98,1899,357],{"class":356},[98,1901,357],{"class":356},[98,1903,357],{"class":356},[98,1905,357],{"class":356},[98,1907,357],{"class":356},[98,1909,1910],{"class":141},"m.Agent.WxNickname,    ",[98,1912,1913],{"class":232},"\u002F\u002F 代理昵称\n",[98,1915,1917,1919,1921,1923,1925,1927,1930],{"class":100,"data-line":1916,"line":1916},73,[98,1918,357],{"class":356},[98,1920,357],{"class":356},[98,1922,357],{"class":356},[98,1924,357],{"class":356},[98,1926,357],{"class":356},[98,1928,1929],{"class":141},"m.PromoterId,          ",[98,1931,1932],{"class":232},"\u002F\u002F 推广员ID\n",[98,1934,1936,1938,1940,1942,1944,1946,1949],{"class":100,"data-line":1935,"line":1935},74,[98,1937,357],{"class":356},[98,1939,357],{"class":356},[98,1941,357],{"class":356},[98,1943,357],{"class":356},[98,1945,357],{"class":356},[98,1947,1948],{"class":141},"m.Promoter.WxNickname, ",[98,1950,1951],{"class":232},"\u002F\u002F 推广员昵称\n",[98,1953,1955,1957,1959,1961,1963,1965],{"class":100,"data-line":1954,"line":1954},75,[98,1956,357],{"class":356},[98,1958,357],{"class":356},[98,1960,357],{"class":356},[98,1962,357],{"class":356},[98,1964,36],{"class":141},[98,1966,450],{"class":372},[98,1968,1970,1972,1974,1976,1978,1981,1983,1986,1988,1990,1992],{"class":100,"data-line":1969,"line":1969},76,[98,1971,357],{"class":356},[98,1973,357],{"class":356},[98,1975,357],{"class":356},[98,1977,357],{"class":356},[98,1979,1980],{"class":141},"rowData",[98,1982,138],{"class":372},[98,1984,1985],{"class":141},"idx",[98,1987,145],{"class":372},[98,1989,122],{"class":141},[98,1991,128],{"class":121},[98,1993,1994],{"class":141}," row\n",[98,1996,1998,2000,2002,2004,2006],{"class":100,"data-line":1997,"line":1997},77,[98,1999,357],{"class":356},[98,2001,357],{"class":356},[98,2003,357],{"class":356},[98,2005,36],{"class":141},[98,2007,450],{"class":137},[98,2009,2011,2013,2015,2017,2019,2021,2023,2025,2027,2030],{"class":100,"data-line":2010,"line":2010},78,[98,2012,357],{"class":356},[98,2014,357],{"class":356},[98,2016,357],{"class":356},[98,2018,1062],{"class":141},[98,2020,1151],{"class":121},[98,2022,1039],{"class":121},[98,2024,939],{"class":104},[98,2026,824],{"class":137},[98,2028,2029],{"class":141},"rowData: rowData, page: currentPage",[98,2031,450],{"class":137},[98,2033,2035,2037,2039,2041,2043,2045,2048],{"class":100,"data-line":2034,"line":2034},79,[98,2036,357],{"class":356},[98,2038,357],{"class":356},[98,2040,36],{"class":141},[98,2042,634],{"class":422},[98,2044,298],{"class":422},[98,2046,2047],{"class":141},"i",[98,2049,377],{"class":422},[98,2051,2053,2055,2057],{"class":100,"data-line":2052,"line":2052},80,[98,2054,357],{"class":356},[98,2056,36],{"class":141},[98,2058,450],{"class":372},[98,2060,2062],{"class":100,"data-line":2061,"line":2061},81,[98,2063,226],{"emptyLinePlaceholder":225},[98,2065,2067,2069,2071,2074,2076],{"class":100,"data-line":2066,"line":2066},82,[98,2068,357],{"class":356},[98,2070,1111],{"class":141},[98,2072,2073],{"class":104},"Wait",[98,2075,298],{"class":372},[98,2077,377],{"class":372},[98,2079,2081,2083,2086,2088,2091],{"class":100,"data-line":2080,"line":2080},83,[98,2082,357],{"class":356},[98,2084,2085],{"class":104},"close",[98,2087,298],{"class":372},[98,2089,2090],{"class":141},"memberCh",[98,2092,377],{"class":372},[98,2094,2096],{"class":100,"data-line":2095,"line":2095},84,[98,2097,226],{"emptyLinePlaceholder":225},[98,2099,2101,2103],{"class":100,"data-line":2100,"line":2100},85,[98,2102,357],{"class":356},[98,2104,2105],{"class":232},"\u002F\u002F 消费者, 并发写Excel不安全，放在主goroutine串行处理\n",[98,2107,2109,2111,2113,2116,2118,2120,2123],{"class":100,"data-line":2108,"line":2108},86,[98,2110,357],{"class":356},[98,2112,1137],{"class":121},[98,2114,2115],{"class":141}," mc ",[98,2117,363],{"class":121},[98,2119,1631],{"class":121},[98,2121,2122],{"class":141}," memberCh ",[98,2124,351],{"class":372},[98,2126,2128,2130,2132,2135,2137,2140,2142,2145,2147],{"class":100,"data-line":2127,"line":2127},87,[98,2129,357],{"class":356},[98,2131,357],{"class":356},[98,2133,2134],{"class":141},"rowStart ",[98,2136,363],{"class":121},[98,2138,2139],{"class":212}," 2",[98,2141,1530],{"class":121},[98,2143,2144],{"class":141}," mc.page",[98,2146,305],{"class":121},[98,2148,2149],{"class":141},"chunkSize\n",[98,2151,2153,2155,2157,2159,2162,2164,2166,2169],{"class":100,"data-line":2152,"line":2152},88,[98,2154,357],{"class":356},[98,2156,357],{"class":356},[98,2158,1137],{"class":121},[98,2160,2161],{"class":141}," idx, row ",[98,2163,363],{"class":121},[98,2165,1631],{"class":121},[98,2167,2168],{"class":141}," mc.rowData ",[98,2170,351],{"class":422},[98,2172,2174,2176,2178,2180,2182,2184,2186,2188,2191,2193,2196,2199,2202,2205,2207,2209,2211,2214],{"class":100,"data-line":2173,"line":2173},89,[98,2175,357],{"class":356},[98,2177,357],{"class":356},[98,2179,357],{"class":356},[98,2181,902],{"class":141},[98,2183,905],{"class":104},[98,2185,298],{"class":137},[98,2187,1483],{"class":141},[98,2189,2190],{"class":104},"Sprintf",[98,2192,298],{"class":372},[98,2194,2195],{"class":108},"\"A",[98,2197,2198],{"class":212},"%d",[98,2200,2201],{"class":108},"\"",[98,2203,2204],{"class":141},", rowStart",[98,2206,1033],{"class":121},[98,2208,1985],{"class":141},[98,2210,311],{"class":372},[98,2212,2213],{"class":141},", row",[98,2215,377],{"class":137},[98,2217,2219,2221,2223,2225],{"class":100,"data-line":2218,"line":2218},90,[98,2220,357],{"class":356},[98,2222,357],{"class":356},[98,2224,36],{"class":141},[98,2226,450],{"class":422},[98,2228,2230,2232,2234],{"class":100,"data-line":2229,"line":2229},91,[98,2231,357],{"class":356},[98,2233,36],{"class":141},[98,2235,450],{"class":372},[98,2237,2239,2241],{"class":100,"data-line":2238,"line":2238},92,[98,2240,357],{"class":356},[98,2242,2243],{"class":232},"\u002F\u002F 将缓冲写入excel\n",[98,2245,2247,2249,2251,2253,2255,2258,2261,2263,2265,2268,2270,2272,2274],{"class":100,"data-line":2246,"line":2246},93,[98,2248,357],{"class":356},[98,2250,384],{"class":121},[98,2252,651],{"class":141},[98,2254,363],{"class":121},[98,2256,2257],{"class":141}," sw.",[98,2259,2260],{"class":104},"Flush",[98,2262,298],{"class":372},[98,2264,311],{"class":372},[98,2266,2267],{"class":141},"; err ",[98,2269,654],{"class":121},[98,2271,402],{"class":212},[98,2273,122],{"class":141},[98,2275,351],{"class":372},[98,2277,2279,2281,2283,2285,2287,2289,2291,2294,2296,2298,2300,2302],{"class":100,"data-line":2278,"line":2278},94,[98,2280,357],{"class":356},[98,2282,357],{"class":356},[98,2284,416],{"class":141},[98,2286,672],{"class":104},[98,2288,298],{"class":422},[98,2290,425],{"class":141},[98,2292,2293],{"class":108},"\"缓冲写入excel失败\"",[98,2295,682],{"class":141},[98,2297,685],{"class":104},[98,2299,298],{"class":137},[98,2301,311],{"class":137},[98,2303,377],{"class":422},[98,2305,2307,2309,2311],{"class":100,"data-line":2306,"line":2306},95,[98,2308,357],{"class":356},[98,2310,36],{"class":141},[98,2312,450],{"class":372},[98,2314,2316],{"class":100,"data-line":2315,"line":2315},96,[98,2317,226],{"emptyLinePlaceholder":225},[98,2319,2321,2323],{"class":100,"data-line":2320,"line":2320},97,[98,2322,357],{"class":356},[98,2324,2325],{"class":232},"\u002F\u002F 设置响应头，提示浏览器下载\n",[98,2327,2329,2331,2334,2337,2339,2342,2344,2347],{"class":100,"data-line":2328,"line":2328},98,[98,2330,357],{"class":356},[98,2332,2333],{"class":141},"c.",[98,2335,2336],{"class":104},"Header",[98,2338,298],{"class":372},[98,2340,2341],{"class":108},"\"Content-Type\"",[98,2343,336],{"class":141},[98,2345,2346],{"class":108},"\"application\u002Fvnd.openxmlformats-officedocument.spreadsheetml.sheet\"",[98,2348,377],{"class":372},[98,2350,2352,2354,2356,2358,2360,2363,2365,2368],{"class":100,"data-line":2351,"line":2351},99,[98,2353,357],{"class":356},[98,2355,2333],{"class":141},[98,2357,2336],{"class":104},[98,2359,298],{"class":372},[98,2361,2362],{"class":108},"\"Content-Disposition\"",[98,2364,336],{"class":141},[98,2366,2367],{"class":108},"\"attachment; filename=report.xlsx\"",[98,2369,377],{"class":372},[98,2371,2373,2375,2377,2379,2381,2384,2386,2389],{"class":100,"data-line":2372,"line":2372},100,[98,2374,357],{"class":356},[98,2376,2333],{"class":141},[98,2378,2336],{"class":104},[98,2380,298],{"class":372},[98,2382,2383],{"class":108},"\"Content-Transfer-Encoding\"",[98,2385,336],{"class":141},[98,2387,2388],{"class":108},"\"binary\"",[98,2390,377],{"class":372},[98,2392,2394],{"class":100,"data-line":2393,"line":2393},101,[98,2395,226],{"emptyLinePlaceholder":225},[98,2397,2399,2401],{"class":100,"data-line":2398,"line":2398},102,[98,2400,357],{"class":356},[98,2402,2403],{"class":232},"\u002F\u002F 把 Excel 内容写入响应\n",[98,2405,2407,2409,2411,2413,2415,2417,2420,2422,2425,2427,2429,2431,2433,2435],{"class":100,"data-line":2406,"line":2406},103,[98,2408,357],{"class":356},[98,2410,384],{"class":121},[98,2412,651],{"class":141},[98,2414,363],{"class":121},[98,2416,746],{"class":141},[98,2418,2419],{"class":104},"Write",[98,2421,298],{"class":372},[98,2423,2424],{"class":141},"c.Writer",[98,2426,311],{"class":372},[98,2428,2267],{"class":141},[98,2430,654],{"class":121},[98,2432,402],{"class":212},[98,2434,122],{"class":141},[98,2436,351],{"class":372},[98,2438,2440,2442,2444,2446,2448,2450,2452,2455,2457,2459,2461,2463],{"class":100,"data-line":2439,"line":2439},104,[98,2441,357],{"class":356},[98,2443,357],{"class":356},[98,2445,416],{"class":141},[98,2447,672],{"class":104},[98,2449,298],{"class":422},[98,2451,425],{"class":141},[98,2453,2454],{"class":108},"\"导出失败\"",[98,2456,682],{"class":141},[98,2458,685],{"class":104},[98,2460,298],{"class":137},[98,2462,311],{"class":137},[98,2464,377],{"class":422},[98,2466,2468,2470,2472],{"class":100,"data-line":2467,"line":2467},105,[98,2469,357],{"class":356},[98,2471,357],{"class":356},[98,2473,440],{"class":121},[98,2475,2477,2479,2481],{"class":100,"data-line":2476,"line":2476},106,[98,2478,357],{"class":356},[98,2480,36],{"class":141},[98,2482,450],{"class":372},[98,2484,2486],{"class":100,"data-line":2485,"line":2485},107,[98,2487,450],{"class":137},[10,2489,2490],{},"对应的日志：",[30,2492,2494],{"className":92,"code":2493,"language":94,"meta":36,"style":36},"2025\u002F09\u002F04 23:59:39 \u002Fcode\u002Fprogram\u002Fcloud-game\u002Fbzv2\u002Fkit\u002Fbzgorm\u002Fdb_read_paginate.go:44 SLOW SQL >= 1s\n[2037.051ms] [rows:10000] SELECT long_id,wx_nickname,created_at,last_online_at,address_last,user_agent_last,vip,pay_count,coin,score,agent_id,promoter_id FROM `member` WHERE `id`>0 ORDER BY `id` DESC LIMIT 10000 OFFSET 90000\n\n2025\u002F09\u002F04 23:59:39 \u002Fcode\u002Fprogram\u002Fcloud-game\u002Fbzv2\u002Fkit\u002Fbzgorm\u002Fdb_read_paginate.go:44 SLOW SQL >= 1s\n[2039.847ms] [rows:10000] SELECT long_id,wx_nickname,created_at,last_online_at,address_last,user_agent_last,vip,pay_count,coin,score,agent_id,promoter_id FROM `member` WHERE `id`>0 ORDER BY `id` DESC LIMIT 10000 OFFSET 60000\n \n# 省略...\n",[38,2495,2496,2517,2570,2574,2594,2648,2654],{"__ignoreMap":36},[98,2497,2498,2500,2503,2505,2507,2509,2511,2513,2515],{"class":100,"data-line":101,"line":101},[98,2499,105],{"class":104},[98,2501,2502],{"class":108}," 23:59:39",[98,2504,112],{"class":108},[98,2506,115],{"class":108},[98,2508,118],{"class":108},[98,2510,122],{"class":121},[98,2512,125],{"class":121},[98,2514,128],{"class":108},[98,2516,131],{"class":108},[98,2518,2519,2521,2524,2526,2528,2530,2532,2534,2536,2538,2540,2542,2544,2546,2548,2550,2552,2554,2556,2558,2560,2562,2564,2566,2568],{"class":100,"data-line":134,"line":134},[98,2520,138],{"class":137},[98,2522,2523],{"class":141},"2037.051ms",[98,2525,145],{"class":137},[98,2527,122],{"class":141},[98,2529,138],{"class":137},[98,2531,152],{"class":141},[98,2533,145],{"class":137},[98,2535,157],{"class":141},[98,2537,160],{"class":108},[98,2539,163],{"class":104},[98,2541,160],{"class":108},[98,2543,168],{"class":104},[98,2545,171],{"class":108},[98,2547,190],{"class":104},[98,2549,160],{"class":108},[98,2551,125],{"class":121},[98,2553,197],{"class":141},[98,2555,160],{"class":108},[98,2557,190],{"class":104},[98,2559,160],{"class":108},[98,2561,206],{"class":104},[98,2563,209],{"class":108},[98,2565,213],{"class":212},[98,2567,216],{"class":108},[98,2569,219],{"class":212},[98,2571,2572],{"class":100,"data-line":222,"line":222},[98,2573,226],{"emptyLinePlaceholder":225},[98,2575,2576,2578,2580,2582,2584,2586,2588,2590,2592],{"class":100,"data-line":229,"line":229},[98,2577,105],{"class":104},[98,2579,2502],{"class":108},[98,2581,112],{"class":108},[98,2583,115],{"class":108},[98,2585,118],{"class":108},[98,2587,122],{"class":121},[98,2589,125],{"class":121},[98,2591,128],{"class":108},[98,2593,131],{"class":108},[98,2595,2596,2598,2601,2603,2605,2607,2609,2611,2613,2615,2617,2619,2621,2623,2625,2627,2629,2631,2633,2635,2637,2639,2641,2643,2645],{"class":100,"data-line":409,"line":409},[98,2597,138],{"class":137},[98,2599,2600],{"class":141},"2039.847ms",[98,2602,145],{"class":137},[98,2604,122],{"class":141},[98,2606,138],{"class":137},[98,2608,152],{"class":141},[98,2610,145],{"class":137},[98,2612,157],{"class":141},[98,2614,160],{"class":108},[98,2616,163],{"class":104},[98,2618,160],{"class":108},[98,2620,168],{"class":104},[98,2622,171],{"class":108},[98,2624,190],{"class":104},[98,2626,160],{"class":108},[98,2628,125],{"class":121},[98,2630,197],{"class":141},[98,2632,160],{"class":108},[98,2634,190],{"class":104},[98,2636,160],{"class":108},[98,2638,206],{"class":104},[98,2640,209],{"class":108},[98,2642,213],{"class":212},[98,2644,216],{"class":108},[98,2646,2647],{"class":212}," 60000\n",[98,2649,2650,2652],{"class":100,"data-line":433,"line":433},[98,2651,122],{"class":356},[98,2653],{"class":141},[98,2655,2656],{"class":100,"data-line":443,"line":443},[98,2657,233],{"class":232},[2659,2660,2661],"blockquote",{},[10,2662,2663],{},"注意：excelize写入是不能并发写入，不然会有数据缺块的问题，后面试了一下顺序插入，excelize只能排序后顺序插入，不要想着获取某一行的行标去并发的写入，这是血的教训",[48,2665,2666],{"start":222},[51,2667,2668,2669,2672,2673,2676],{},"最后我想了一下，使用",[43,2670,2671],{},"游标分页","，先利用主键的索引去快速找到上一页的lastId，然后使",[38,2674,2675],{"code":2675},"id>lastId","，避免使用大offset跳表带来的性能开销",[30,2678,2680],{"className":279,"code":2679,"language":281,"meta":36,"style":36},"\u002F\u002F 优化：使用 lastId 作为子查询条件，避免大 OFFSET 性能问题\nvar lastId uint\nif currentPage > 0 {\n    \u002F\u002F 只在第一页之后查找 lastId\n    subQuery := s.deviceDB.Engine.Table(\"member\").\n    Select(\"id\").\n    Scopes(func(tx *gorm.DB) *gorm.DB {\n        tx = s.memberListSearchFilterFunc(param)(tx)\n        return tx.Unscoped().Scopes(filterFunc, s.sysUserMemberFilter(user))\n    }).\n    Order(\"`id`\").\n    Limit(1).\n    Offset(currentPage * chunkSize - 1)\n    if err := subQuery.Pluck(\"id\", &lastId).Error; err != nil {\n        bzgin.ErrorResponse(c, \"lastId获取失败\", err.Error())\n        return\n    }\n}\n\nquery := s.deviceDB.Engine.Debug().Table(\"member\").\n\t\tSelect(\"long_id,member.wx_nickname,member.created_at,member.last_online_at,member.address_last,member.user_agent_last,member.vip,member.pay_count,member.coin,member.score,member.agent_id,s1.wx_nickname AS agent_wx_nickname,member.promoter_id,s2.wx_nickname AS promoter_wx_nickname\").\nJoins(\"LEFT JOIN cloud_game_admin.sys_user AS s1 ON member.agent_id = s1.user_id\").\nJoins(\"LEFT JOIN cloud_game_admin.sys_user AS s2 ON member.promoter_id = s2.user_id\").\nScopes(func(tx *gorm.DB) *gorm.DB {\n    tx = s.memberListSearchFilterFunc(param)(tx)\n    return tx.Unscoped().Scopes(filterFunc, s.sysUserMemberFilter(user))\n}).\nOrder(\"`id`\").\nLimit(chunkSize)\n\nif currentPage > 0 && lastId > 0 {\n    query = query.Where(\"member.id > ?\", lastId)\n}\n",[38,2681,2682,2687,2697,2712,2720,2744,2759,2797,2823,2857,2869,2884,2900,2922,2963,2990,2998,3006,3010,3014,3041,3058,3072,3085,3121,3145,3177,3185,3197,3207,3211,3234,3258],{"__ignoreMap":36},[98,2683,2684],{"class":100,"data-line":101,"line":101},[98,2685,2686],{"class":232},"\u002F\u002F 优化：使用 lastId 作为子查询条件，避免大 OFFSET 性能问题\n",[98,2688,2689,2691,2694],{"class":100,"data-line":134,"line":134},[98,2690,1092],{"class":121},[98,2692,2693],{"class":141}," lastId ",[98,2695,2696],{"class":121},"uint\n",[98,2698,2699,2701,2704,2706,2708,2710],{"class":100,"data-line":222,"line":222},[98,2700,384],{"class":121},[98,2702,2703],{"class":141}," currentPage ",[98,2705,125],{"class":121},[98,2707,1145],{"class":212},[98,2709,122],{"class":141},[98,2711,351],{"class":137},[98,2713,2714,2717],{"class":100,"data-line":229,"line":229},[98,2715,2716],{"class":356},"    ",[98,2718,2719],{"class":232},"\u002F\u002F 只在第一页之后查找 lastId\n",[98,2721,2722,2724,2727,2729,2732,2735,2737,2740,2742],{"class":100,"data-line":409,"line":409},[98,2723,2716],{"class":356},[98,2725,2726],{"class":141},"subQuery ",[98,2728,363],{"class":121},[98,2730,2731],{"class":141}," s.deviceDB.Engine.",[98,2733,2734],{"class":104},"Table",[98,2736,298],{"class":372},[98,2738,2739],{"class":108},"\"member\"",[98,2741,311],{"class":372},[98,2743,1341],{"class":141},[98,2745,2746,2748,2750,2752,2755,2757],{"class":100,"data-line":433,"line":433},[98,2747,2716],{"class":356},[98,2749,1357],{"class":104},[98,2751,298],{"class":372},[98,2753,2754],{"class":108},"\"id\"",[98,2756,311],{"class":372},[98,2758,1341],{"class":141},[98,2760,2761,2763,2765,2767,2769,2771,2773,2775,2777,2779,2781,2783,2785,2787,2789,2791,2793,2795],{"class":100,"data-line":443,"line":443},[98,2762,2716],{"class":356},[98,2764,595],{"class":104},[98,2766,298],{"class":372},[98,2768,293],{"class":121},[98,2770,298],{"class":422},[98,2772,515],{"class":301},[98,2774,324],{"class":121},[98,2776,520],{"class":104},[98,2778,330],{"class":141},[98,2780,525],{"class":104},[98,2782,311],{"class":422},[98,2784,122],{"class":141},[98,2786,305],{"class":121},[98,2788,520],{"class":104},[98,2790,330],{"class":141},[98,2792,525],{"class":104},[98,2794,122],{"class":141},[98,2796,351],{"class":422},[98,2798,2799,2801,2803,2805,2807,2809,2811,2813,2815,2817,2819,2821],{"class":100,"data-line":453,"line":453},[98,2800,2716],{"class":356},[98,2802,2716],{"class":356},[98,2804,551],{"class":141},[98,2806,128],{"class":121},[98,2808,468],{"class":141},[98,2810,558],{"class":104},[98,2812,298],{"class":137},[98,2814,339],{"class":141},[98,2816,311],{"class":137},[98,2818,298],{"class":137},[98,2820,515],{"class":141},[98,2822,377],{"class":137},[98,2824,2825,2827,2829,2831,2833,2835,2837,2839,2841,2843,2845,2847,2849,2851,2853,2855],{"class":100,"data-line":458,"line":458},[98,2826,2716],{"class":356},[98,2828,2716],{"class":356},[98,2830,580],{"class":121},[98,2832,583],{"class":141},[98,2834,586],{"class":104},[98,2836,298],{"class":137},[98,2838,311],{"class":137},[98,2840,330],{"class":141},[98,2842,595],{"class":104},[98,2844,298],{"class":137},[98,2846,600],{"class":141},[98,2848,603],{"class":104},[98,2850,298],{"class":372},[98,2852,608],{"class":141},[98,2854,311],{"class":372},[98,2856,377],{"class":137},[98,2858,2859,2861,2863,2865,2867],{"class":100,"data-line":480,"line":480},[98,2860,2716],{"class":356},[98,2862,36],{"class":141},[98,2864,634],{"class":422},[98,2866,311],{"class":372},[98,2868,1341],{"class":141},[98,2870,2871,2873,2875,2877,2880,2882],{"class":100,"data-line":485,"line":485},[98,2872,2716],{"class":356},[98,2874,617],{"class":104},[98,2876,298],{"class":372},[98,2878,2879],{"class":108},"\"`id`\"",[98,2881,311],{"class":372},[98,2883,1341],{"class":141},[98,2885,2886,2888,2891,2893,2896,2898],{"class":100,"data-line":493,"line":493},[98,2887,2716],{"class":356},[98,2889,2890],{"class":104},"Limit",[98,2892,298],{"class":372},[98,2894,2895],{"class":212},"1",[98,2897,311],{"class":372},[98,2899,1341],{"class":141},[98,2901,2902,2904,2907,2909,2912,2914,2916,2918,2920],{"class":100,"data-line":544,"line":544},[98,2903,2716],{"class":356},[98,2905,2906],{"class":104},"Offset",[98,2908,298],{"class":372},[98,2910,2911],{"class":141},"currentPage ",[98,2913,305],{"class":121},[98,2915,1036],{"class":141},[98,2917,1039],{"class":121},[98,2919,1042],{"class":212},[98,2921,377],{"class":372},[98,2923,2924,2926,2928,2930,2932,2935,2938,2940,2942,2944,2947,2950,2952,2955,2957,2959,2961],{"class":100,"data-line":573,"line":573},[98,2925,2716],{"class":356},[98,2927,384],{"class":121},[98,2929,651],{"class":141},[98,2931,363],{"class":121},[98,2933,2934],{"class":141}," subQuery.",[98,2936,2937],{"class":104},"Pluck",[98,2939,298],{"class":372},[98,2941,2754],{"class":108},[98,2943,336],{"class":141},[98,2945,2946],{"class":121},"&",[98,2948,2949],{"class":141},"lastId",[98,2951,311],{"class":372},[98,2953,2954],{"class":141},".Error; err ",[98,2956,654],{"class":121},[98,2958,402],{"class":212},[98,2960,122],{"class":141},[98,2962,351],{"class":372},[98,2964,2965,2967,2969,2971,2973,2975,2977,2980,2982,2984,2986,2988],{"class":100,"data-line":627,"line":627},[98,2966,2716],{"class":356},[98,2968,2716],{"class":356},[98,2970,416],{"class":141},[98,2972,672],{"class":104},[98,2974,298],{"class":422},[98,2976,425],{"class":141},[98,2978,2979],{"class":108},"\"lastId获取失败\"",[98,2981,682],{"class":141},[98,2983,685],{"class":104},[98,2985,298],{"class":137},[98,2987,311],{"class":137},[98,2989,377],{"class":422},[98,2991,2992,2994,2996],{"class":100,"data-line":639,"line":639},[98,2993,2716],{"class":356},[98,2995,2716],{"class":356},[98,2997,440],{"class":121},[98,2999,3000,3002,3004],{"class":100,"data-line":644,"line":644},[98,3001,2716],{"class":356},[98,3003,36],{"class":141},[98,3005,450],{"class":372},[98,3007,3008],{"class":100,"data-line":663,"line":663},[98,3009,450],{"class":137},[98,3011,3012],{"class":100,"data-line":694,"line":694},[98,3013,226],{"emptyLinePlaceholder":225},[98,3015,3016,3019,3021,3023,3025,3027,3029,3031,3033,3035,3037,3039],{"class":100,"data-line":703,"line":703},[98,3017,3018],{"class":141},"query ",[98,3020,363],{"class":121},[98,3022,2731],{"class":141},[98,3024,1280],{"class":104},[98,3026,298],{"class":137},[98,3028,311],{"class":137},[98,3030,330],{"class":141},[98,3032,2734],{"class":104},[98,3034,298],{"class":137},[98,3036,2739],{"class":108},[98,3038,311],{"class":137},[98,3040,1341],{"class":141},[98,3042,3043,3045,3047,3049,3051,3054,3056],{"class":100,"data-line":708,"line":708},[98,3044,357],{"class":356},[98,3046,357],{"class":356},[98,3048,1357],{"class":104},[98,3050,298],{"class":137},[98,3052,3053],{"class":108},"\"long_id,member.wx_nickname,member.created_at,member.last_online_at,member.address_last,member.user_agent_last,member.vip,member.pay_count,member.coin,member.score,member.agent_id,s1.wx_nickname AS agent_wx_nickname,member.promoter_id,s2.wx_nickname AS promoter_wx_nickname\"",[98,3055,311],{"class":137},[98,3057,1341],{"class":141},[98,3059,3060,3063,3065,3068,3070],{"class":100,"data-line":716,"line":716},[98,3061,3062],{"class":104},"Joins",[98,3064,298],{"class":137},[98,3066,3067],{"class":108},"\"LEFT JOIN cloud_game_admin.sys_user AS s1 ON member.agent_id = s1.user_id\"",[98,3069,311],{"class":137},[98,3071,1341],{"class":141},[98,3073,3074,3076,3078,3081,3083],{"class":100,"data-line":736,"line":736},[98,3075,3062],{"class":104},[98,3077,298],{"class":137},[98,3079,3080],{"class":108},"\"LEFT JOIN cloud_game_admin.sys_user AS s2 ON member.promoter_id = s2.user_id\"",[98,3082,311],{"class":137},[98,3084,1341],{"class":141},[98,3086,3087,3089,3091,3093,3095,3097,3099,3101,3103,3105,3107,3109,3111,3113,3115,3117,3119],{"class":100,"data-line":759,"line":759},[98,3088,595],{"class":104},[98,3090,298],{"class":137},[98,3092,293],{"class":121},[98,3094,298],{"class":372},[98,3096,515],{"class":301},[98,3098,324],{"class":121},[98,3100,520],{"class":104},[98,3102,330],{"class":141},[98,3104,525],{"class":104},[98,3106,311],{"class":372},[98,3108,122],{"class":141},[98,3110,305],{"class":121},[98,3112,520],{"class":104},[98,3114,330],{"class":141},[98,3116,525],{"class":104},[98,3118,122],{"class":141},[98,3120,351],{"class":372},[98,3122,3123,3125,3127,3129,3131,3133,3135,3137,3139,3141,3143],{"class":100,"data-line":776,"line":776},[98,3124,2716],{"class":356},[98,3126,551],{"class":141},[98,3128,128],{"class":121},[98,3130,468],{"class":141},[98,3132,558],{"class":104},[98,3134,298],{"class":422},[98,3136,339],{"class":141},[98,3138,311],{"class":422},[98,3140,298],{"class":422},[98,3142,515],{"class":141},[98,3144,377],{"class":422},[98,3146,3147,3149,3151,3153,3155,3157,3159,3161,3163,3165,3167,3169,3171,3173,3175],{"class":100,"data-line":796,"line":796},[98,3148,2716],{"class":356},[98,3150,580],{"class":121},[98,3152,583],{"class":141},[98,3154,586],{"class":104},[98,3156,298],{"class":422},[98,3158,311],{"class":422},[98,3160,330],{"class":141},[98,3162,595],{"class":104},[98,3164,298],{"class":422},[98,3166,600],{"class":141},[98,3168,603],{"class":104},[98,3170,298],{"class":137},[98,3172,608],{"class":141},[98,3174,311],{"class":137},[98,3176,377],{"class":422},[98,3178,3179,3181,3183],{"class":100,"data-line":805,"line":805},[98,3180,634],{"class":372},[98,3182,311],{"class":137},[98,3184,1341],{"class":141},[98,3186,3187,3189,3191,3193,3195],{"class":100,"data-line":897,"line":897},[98,3188,617],{"class":104},[98,3190,298],{"class":137},[98,3192,2879],{"class":108},[98,3194,311],{"class":137},[98,3196,1341],{"class":141},[98,3198,3199,3201,3203,3205],{"class":100,"data-line":918,"line":918},[98,3200,2890],{"class":104},[98,3202,298],{"class":137},[98,3204,1538],{"class":141},[98,3206,377],{"class":137},[98,3208,3209],{"class":100,"data-line":923,"line":923},[98,3210,226],{"emptyLinePlaceholder":225},[98,3212,3213,3215,3217,3219,3221,3224,3226,3228,3230,3232],{"class":100,"data-line":931,"line":931},[98,3214,384],{"class":121},[98,3216,2703],{"class":141},[98,3218,125],{"class":121},[98,3220,1145],{"class":212},[98,3222,3223],{"class":121}," &&",[98,3225,2693],{"class":141},[98,3227,125],{"class":121},[98,3229,1145],{"class":212},[98,3231,122],{"class":141},[98,3233,351],{"class":137},[98,3235,3236,3238,3240,3242,3245,3248,3250,3253,3256],{"class":100,"data-line":949,"line":949},[98,3237,2716],{"class":356},[98,3239,3018],{"class":141},[98,3241,128],{"class":121},[98,3243,3244],{"class":141}," query.",[98,3246,3247],{"class":104},"Where",[98,3249,298],{"class":372},[98,3251,3252],{"class":108},"\"member.id > ?\"",[98,3254,3255],{"class":141},", lastId",[98,3257,377],{"class":372},[98,3259,3260],{"class":100,"data-line":970,"line":970},[98,3261,450],{"class":137},[10,3263,3264],{},"对应日志",[30,3266,3268],{"className":92,"code":3267,"language":94,"meta":36,"style":36},"2025\u002F09\u002F05 10:48:45 \u002Fcode\u002Fprogram\u002Fcloud-game\u002Fcloud-game-hub-jxcw\u002Fadmin-h5-server\u002Finternal\u002Fservice\u002Flpj_service_member.go:448\n[284.715ms] [rows:10000] SELECT long_id,member.wx_nickname,member.created_at,member.last_online_at,member.address_last,member.user_agent_last,member.vip,member.pay_count,member.coin,member.score,member.agent_id,s1.wx_nickname AS agent_wx_nickname,member.promoter_id,s2.wx_nickname AS promoter_wx_nickname FROM `member` LEFT JOIN cloud_game_admin.sys_user AS s1 ON member.agent_id = s1.user_id LEFT JOIN cloud_game_admin.sys_user AS s2 ON member.promoter_id = s2.user_id WHERE `id`>0 ORDER BY `id` LIMIT 10000\n\n2025\u002F09\u002F05 10:48:45 \u002Fcode\u002Fprogram\u002Fcloud-game\u002Fcloud-game-hub-jxcw\u002Fadmin-h5-server\u002Finternal\u002Fservice\u002Flpj_service_member.go:448\n[394.829ms] [rows:10000] SELECT long_id,member.wx_nickname,member.created_at,member.last_online_at,member.address_last,member.user_agent_last,member.vip,member.pay_count,member.coin,member.score,member.agent_id,s1.wx_nickname AS agent_wx_nickname,member.promoter_id,s2.wx_nickname AS promoter_wx_nickname FROM `member` LEFT JOIN cloud_game_admin.sys_user AS s1 ON member.agent_id = s1.user_id LEFT JOIN cloud_game_admin.sys_user AS s2 ON member.promoter_id = s2.user_id WHERE member.id > 20042 AND `id`>0 ORDER BY `id` LIMIT 10000\n",[38,3269,3270,3281,3378,3382,3390],{"__ignoreMap":36},[98,3271,3272,3275,3278],{"class":100,"data-line":101,"line":101},[98,3273,3274],{"class":104},"2025\u002F09\u002F05",[98,3276,3277],{"class":108}," 10:48:45",[98,3279,3280],{"class":108}," \u002Fcode\u002Fprogram\u002Fcloud-game\u002Fcloud-game-hub-jxcw\u002Fadmin-h5-server\u002Finternal\u002Fservice\u002Flpj_service_member.go:448\n",[98,3282,3283,3285,3288,3290,3292,3294,3296,3298,3301,3303,3305,3307,3310,3313,3316,3319,3322,3325,3328,3331,3334,3336,3338,3340,3342,3345,3347,3350,3352,3355,3357,3359,3361,3363,3365,3367,3369,3371,3373,3375],{"class":100,"data-line":134,"line":134},[98,3284,138],{"class":137},[98,3286,3287],{"class":141},"284.715ms",[98,3289,145],{"class":137},[98,3291,122],{"class":141},[98,3293,138],{"class":137},[98,3295,152],{"class":141},[98,3297,145],{"class":137},[98,3299,3300],{"class":141}," SELECT long_id,member.wx_nickname,member.created_at,member.last_online_at,member.address_last,member.user_agent_last,member.vip,member.pay_count,member.coin,member.score,member.agent_id,s1.wx_nickname AS agent_wx_nickname,member.promoter_id,s2.wx_nickname AS promoter_wx_nickname FROM ",[98,3302,160],{"class":108},[98,3304,163],{"class":104},[98,3306,160],{"class":108},[98,3308,3309],{"class":104}," LEFT",[98,3311,3312],{"class":108}," JOIN",[98,3314,3315],{"class":108}," cloud_game_admin.sys_user",[98,3317,3318],{"class":108}," AS",[98,3320,3321],{"class":108}," s1",[98,3323,3324],{"class":108}," ON",[98,3326,3327],{"class":108}," member.agent_id",[98,3329,3330],{"class":108}," =",[98,3332,3333],{"class":108}," s1.user_id",[98,3335,3309],{"class":108},[98,3337,3312],{"class":108},[98,3339,3315],{"class":108},[98,3341,3318],{"class":108},[98,3343,3344],{"class":108}," s2",[98,3346,3324],{"class":108},[98,3348,3349],{"class":108}," member.promoter_id",[98,3351,3330],{"class":108},[98,3353,3354],{"class":108}," s2.user_id",[98,3356,168],{"class":108},[98,3358,171],{"class":108},[98,3360,190],{"class":104},[98,3362,160],{"class":108},[98,3364,125],{"class":121},[98,3366,197],{"class":141},[98,3368,160],{"class":108},[98,3370,190],{"class":104},[98,3372,160],{"class":108},[98,3374,209],{"class":104},[98,3376,3377],{"class":212}," 10000\n",[98,3379,3380],{"class":100,"data-line":222,"line":222},[98,3381,226],{"emptyLinePlaceholder":225},[98,3383,3384,3386,3388],{"class":100,"data-line":229,"line":229},[98,3385,3274],{"class":104},[98,3387,3277],{"class":108},[98,3389,3280],{"class":108},[98,3391,3392,3394,3397,3399,3401,3403,3405,3407,3409,3411,3413,3415,3417,3419,3421,3423,3425,3427,3429,3431,3433,3435,3437,3439,3441,3443,3445,3447,3449,3451,3453,3456,3458,3460,3463,3465,3467,3469,3471,3473,3475,3477,3479,3481,3483],{"class":100,"data-line":409,"line":409},[98,3393,138],{"class":137},[98,3395,3396],{"class":141},"394.829ms",[98,3398,145],{"class":137},[98,3400,122],{"class":141},[98,3402,138],{"class":137},[98,3404,152],{"class":141},[98,3406,145],{"class":137},[98,3408,3300],{"class":141},[98,3410,160],{"class":108},[98,3412,163],{"class":104},[98,3414,160],{"class":108},[98,3416,3309],{"class":104},[98,3418,3312],{"class":108},[98,3420,3315],{"class":108},[98,3422,3318],{"class":108},[98,3424,3321],{"class":108},[98,3426,3324],{"class":108},[98,3428,3327],{"class":108},[98,3430,3330],{"class":108},[98,3432,3333],{"class":108},[98,3434,3309],{"class":108},[98,3436,3312],{"class":108},[98,3438,3315],{"class":108},[98,3440,3318],{"class":108},[98,3442,3344],{"class":108},[98,3444,3324],{"class":108},[98,3446,3349],{"class":108},[98,3448,3330],{"class":108},[98,3450,3354],{"class":108},[98,3452,168],{"class":108},[98,3454,3455],{"class":108}," member.id",[98,3457,122],{"class":121},[98,3459,125],{"class":121},[98,3461,3462],{"class":212}," 20042",[98,3464,185],{"class":108},[98,3466,171],{"class":108},[98,3468,190],{"class":104},[98,3470,160],{"class":108},[98,3472,125],{"class":121},[98,3474,197],{"class":141},[98,3476,160],{"class":108},[98,3478,190],{"class":104},[98,3480,160],{"class":108},[98,3482,209],{"class":104},[98,3484,3377],{"class":212},[26,3486,3487],{"id":3487},"总结",[10,3489,3490],{},"经过这次实践，我对sql调优有了初步的认知",[48,3492,3493,3496,3499,3502,3505],{},[51,3494,3495],{},"为查询的字段建立合适的索引",[51,3497,3498],{},"只返回需要的字段【看起来不重要，实则很有用】",[51,3500,3501],{},"利用子查询【即通过primary key返回的id或idList】当作条件，相比全表排序后利用Index快",[51,3503,3504],{},"使用游标分页，记录lastId",[51,3506,3507],{},"合理使用Explain关键字",[3509,3510,3511],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sSDpw, html code.shiki .sSDpw{--shiki-default:#005cc5;--shiki-dark:#79b8ff}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJX2D, html code.shiki .sJX2D{--shiki-default:#e36209;--shiki-dark:#ffab70}html pre.shiki code .sqkie, html code.shiki .sqkie{--shiki-default:#5a32a3;--shiki-dark:#b392f0}",{"title":36,"searchDepth":229,"depth":229,"links":3513},[3514,3515,3516],{"id":28,"depth":134,"text":28},{"id":84,"depth":134,"text":84},{"id":3487,"depth":134,"text":3487},[3518],"数据库","2025-09-05","这篇文章记录了一次大数据报表导出的优化实践。业务需求要求一次性导出10万条数据到Excel，最初采用全表扫描配合OFFSET分页，单次导出耗时超过30秒。经过分析慢查询日志，发现主要瓶颈在SQL层面和Excel写入方式。优化过程包括：只查询必要字段、去除无效条件、并发分片查询、流式写入Excel、最后引入游标分页避免大OFFSET扫描。最终导出耗时降至8秒。本文总结了SQL调优、分页策略以及大规模数据导出的关键经验。",false,"md",null,{"slots":3525},{},"\u002F2025\u002F09\u002Freport-export-optimization-from-offset-to-cursor-pagination",{"text":3528,"minutes":3529,"time":3530,"words":3531},"8 min read",7.44,446400,1488,{"title":5,"description":3520},{"loc":3526},"posts\u002F2025\u002F09\u002Freport-export-optimization-from-offset-to-cursor-pagination",[3536,3537],"goroutine","sql","tech","xxsJIhZGsFuMSeUVDoEjjmB8cSFDv7QWtXOdj9bSFJw",[3541,3546],{"title":3542,"path":3543,"stem":3544,"date":3545,"type":3538,"children":-1},"不急于求成，才是最长远的成长","\u002F2025\u002F09\u002Fthe-courage-to-grow-slowly","posts\u002F2025\u002F09\u002Fthe-courage-to-grow-slowly","2025-09-01",{"title":3547,"path":3548,"stem":3549,"date":3550,"type":3538,"children":-1},"Redis 通用键命令详解","\u002F2025\u002F09\u002Fredis-common-commands","posts\u002F2025\u002F09\u002Fredis-common-commands","2025-09-10",1786555055582]