Board logo

标题: 【已解决】WPS从10万条数据中找记录,耗时1小时,有什么快的方法 [打印本页]

作者: 朱科技    时间: 2021-8-7 19:54     标题: 【已解决】WPS从10万条数据中找记录,耗时1小时,有什么快的方法

本帖最后由 朱科技 于 2022-12-28 10:40 编辑

WPS从10万条数据中找记录,耗时1小时,有什么快的方法
附件链接: https://pan.baidu.com/s/1utKLL5Dwxeu3MgR1AcnErQ 提取码: khw2
作者: a20150604    时间: 2021-8-7 20:15

样例文件怎样的
作者: newswan    时间: 2021-8-7 20:27

wps?
用 excel 试试
或者导出 csv 用 grep
作者: 朱科技    时间: 2021-8-7 21:07

无法上传附件呀
作者: 朱科技    时间: 2021-8-7 21:07

回复 2# a20150604


    上传不了附件
作者: 朱科技    时间: 2021-8-7 21:07

回复 3# newswan


    上传不了附件
作者: 朱科技    时间: 2021-8-7 21:18

附件https://club.excelhome.net/forum ... ;page=1#pid10748534
作者: a20150604    时间: 2021-8-7 22:47

回复 7# 朱科技


    你怎么操作的,要那么长时间
作者: slimay    时间: 2021-8-8 12:39

本帖最后由 slimay 于 2021-8-8 15:26 编辑

解法零:WPS函数法 也只用2秒
在明细中构造 列并 G列=A2&":"&E2&":"&F2,  行号 H列 = ROW(A2)下拉扩展所有行
然后使用vlookup直接检索列并 G列的内容  = VLOOKUP("YT5692687908699:无锡中心:下车扫描",  明细!G:H,2,FALSE)
返回的就是行号. 通过构造列并, 将查询耗时缩短到 2秒左右.亲测6万行只需1秒左右
  1. 查询订单号 查询集散地 查询扫描状态
  2. YT5692687908699 无锡中心 下车扫描
  3. 查询结果(列并) 查询到的行号
  4. YT5692687908699:无锡中心:下车扫描 11
复制代码
解法一: C语言 20万行 0.01秒实测
这种问题,不用C,你很难做到毫秒级解决问题
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #define LINE_SIZE 1024
  6. char* yundanSN = "YT5692687908699";
  7. char* yundanAddress = "无锡中心";
  8. char* yundanState = "下车扫描";
  9. int main( int argc, char** argv )
  10. {
  11. if(argc != 2)
  12. {
  13. printf("Usage: argv[0] \"*.csv\"\n");
  14. exit(1);
  15. }
  16. FILE* fp = fopen(argv[1], "rb");
  17. if(fp == NULL)
  18. {
  19. printf("%s\n", "Error list file.");
  20. exit(1);
  21. }
  22. char line[LINE_SIZE + 1];
  23. line[0] = 0x00;
  24. int lineNum = 0;
  25. while(! feof(fp))
  26. {
  27. lineNum ++;
  28. fgets(line, LINE_SIZE, fp);
  29. if(strstr(line, yundanSN) && strstr(line, yundanAddress) && strstr(line, yundanState))
  30. {
  31. printf("SN:%s, LINE_SN:%d\n", yundanSN, lineNum);
  32. break;
  33. }
  34. }
  35. fclose(fp);
  36. return 0;
  37. }
复制代码
解法二: 批处理 2万行 10秒实测
批处理搞定
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "查询运单编号=YT5692687908699"
  4. set "查询运单地址=无锡中心"
  5. set "查询运单状态=下车扫描"
  6. set 行号=0
  7. for /f "delims=, tokens=1-3" %%a in ('more +35 "%~f0"') do (
  8. set/a "行号+=1"
  9. if not defined #%%a (
  10. if "%%a"=="%查询运单编号%" (
  11. if "%%b"=="%查询运单地址%" (
  12. if "%%c"=="%查询运单状态%" (
  13. set "#%%a=!行号!"
  14. )
  15. )
  16. )
  17. )
  18. )
  19. echo 运单编号         行号
  20. for /f "tokens=1,2 delims=#=" %%a in ('set #') do (
  21. echo;%%a  %%b
  22. )
  23. pause
  24. REM 数据粘贴区
  25. 运单号,操作时间,操作频次,操作网点编号,操作网点名称,操作名称
  26. YT5692687908699,2,3,4,广东省江门市,业务员收件
  27. YT5692687908699,2,3,4,广东省江门市,揽收扫描
  28. YT5692687908699,,,,广东省江门市,下车扫描
  29. YT5692687908699,,,,广东省江门市,装件入包扫描
  30. YT5692687908699,,,,广东省江门市,装件入车扫描
  31. YT5692687908699,,,,广东省江门市,发车扫描
  32. YT5692687908699,,,,江门中心,到车扫描
  33. YT5692687908699,,,,江门中心,下车扫描
  34. YT5692687908699,,,,江门中心,装件入车扫描
  35. YT5692687908699,,,,无锡中心,下车扫描
  36. YT5692687908699,,,,无锡中心,下车扫描
  37. YT5692687908699,,,,无锡中心,装件入车扫描
  38. YT5692687908699,,,,新区春潮一部,下车扫描
  39. YT5692687908699,,,,经济开发区,下车扫描
  40. YT5692687908699,,,,经济开发区,装件入车扫描
  41. YT5692687908699,,,,无锡中心,下车扫描
  42. YT5692687908699,,,,无锡中心,装件入车扫描
  43. YT5692687908699,,,,新区,下车扫描
  44. YT5692687908699,2,3,4,广东省江门市,业务员收件
  45. YT5692687908699,2,3,4,广东省江门市,揽收扫描
  46. YT5692687908699,,,,广东省江门市,下车扫描
  47. YT5692687908699,,,,广东省江门市,装件入包扫描
  48. YT5692687908699,,,,广东省江门市,装件入车扫描
  49. YT5692687908699,,,,广东省江门市,发车扫描
  50. YT5692687908699,,,,江门中心,到车扫描
  51. YT5692687908699,,,,江门中心,下车扫描
  52. YT5692687908699,,,,江门中心,装件入车扫描
  53. YT5692687908699,,,,无锡中心,下车扫描
  54. YT5692687908699,,,,无锡中心,下车扫描
  55. YT5692687908699,,,,无锡中心,装件入车扫描
  56. YT5692687908699,,,,新区春潮一部,下车扫描
  57. YT5692687908699,,,,经济开发区,下车扫描
  58. YT5692687908699,,,,经济开发区,装件入车扫描
  59. YT5692687908699,,,,无锡中心,下车扫描
  60. YT5692687908699,,,,无锡中心,装件入车扫描
  61. YT5692687908699,,,,新区,下车扫描
  62. YT5692687908699,2,3,4,广东省江门市,业务员收件
  63. YT5692687908699,2,3,4,广东省江门市,揽收扫描
  64. YT5692687908699,,,,广东省江门市,下车扫描
  65. YT5692687908699,,,,广东省江门市,装件入包扫描
  66. YT5692687908699,,,,广东省江门市,装件入车扫描
  67. YT5692687908699,,,,广东省江门市,发车扫描
  68. YT5692687908699,,,,江门中心,到车扫描
  69. YT5692687908699,,,,江门中心,下车扫描
复制代码

作者: 朱科技    时间: 2021-8-8 15:36

表1有5000条,明细表有20万条,用VB宏能行吗
作者: 朱科技    时间: 2021-8-8 15:36

回复 9# slimay


   
表1有5000条,明细表有20万条,用VB宏能行吗
作者: slimay    时间: 2021-8-8 16:56

本帖最后由 slimay 于 2021-8-8 17:05 编辑

回复 11# 朱科技
可以的,用来VB宏,连vlookup都省了, VB直接就能for循环, 不需要vlookup了,但是你的程序要兼容VB宏, 不同电脑对VB宏的兼容性不一样. 我以前写过宏,但是放到别的电脑上运行,出现宏兼容性问题.
就用vlookup吧,添加两列辅助列,  5000行, 20万数据源也是十几秒出结果.
如果用C语言, 多线程, 关键词编码, 实现上亿条数据的查询,也是不超过5秒. 你就是把五大快递公司的数据都弄过来,我用C查也不会超过30秒.十几亿级数据并发高速查询
作者: 朱科技    时间: 2021-8-8 17:06

回复 12# slimay


    实际操作和你说的不切实际,取值确实 是耗时40分钟-小时左右
作者: slimay    时间: 2021-8-8 17:09

本帖最后由 slimay 于 2021-8-8 17:10 编辑

回复 13# 朱科技
我用的100元的CPU,也就1秒出结果了,你把你的函数贴出来, 我看看你怎么写的,不会这么慢的, 肯定是你的表格函数有问题,做了无用的功,导致反应变慢
作者: 朱科技    时间: 2021-8-8 17:17

回复 14# slimay


    有6列都是用的这个公式,也就是6列5000行
=SMALL(IFERROR(IF((走件流程!$A$1A$600000=C4)*(走件流程!$E$1:$E$600000="无锡转运中心")*(走件流程!$F$1:$F$600000="下车扫描"),ROW(走件流程!$E$1:$E$600000)),9^9),1)
作者: slimay    时间: 2021-8-8 17:33

回复 15# 朱科技
写的逻辑很糟糕, 问题很大. 怪不得速度慢了
作者: 523066680    时间: 2021-8-8 19:18

本帖最后由 523066680 于 2021-8-8 22:20 编辑

如果表1要处理的项目有10W条,明细(走件流程)的数据有60W条。按先查找单号,后判断操作网点名称,最后判断操作名称,那确实要些时间的,10W*60W*三个判断(大致的,不精确)。

VBA不熟,不够思路大概这样:
创建字典,先筛选 网点名称 和 操作状态 符合的所有单号+行号存储到字典,
然后遍历表1,获取匹配单号的行号填入。

但如果表1待查的每一项,网点名称 和 操作状态 的值不一定一致,每次都需要做判断,用支持哈希表的语言处理好用一些,
我大概会这么创建:$hash{操作名称}{网点名称}{单号} = 行号
(内存占用还未测试)

另外就是数据的读写,最好是整块读出和写入,逐行处理时调用接口的消耗会被10W倍放大
作者: a20150604    时间: 2021-8-8 19:44

相当于 比对数据 A 和 数据 B, 为其中一者建字典, 优先选两者中规模小的, 因为 建字典过程 耗时也正相关于 数据规模;

而后的 比对过程  比对量 = 数据A 规模 * 数据 B 规模, 基本固定
作者: slimay    时间: 2021-8-8 20:51

本帖最后由 slimay 于 2021-8-8 21:06 编辑

回复 17# 523066680

可以先对表格筛选啊, 先筛选出 包含 "下车扫描" 的表1,  然后 在这个新表中筛选出 包含 "无锡中心"  的 表2,  然后表2就是很小的范围 , 在匹配单号时(先用表格的排序功能排好序), 单号后几位都是纯数字,  可以二分折半查询, 这样他就是有60万行数据 也只需  循环 几万次就搞定了.即使用C语言, 按这个思路,也是控制在一秒内搞定.
他的描述就是 : 只要无锡中心 下车扫描的 运单号的行数,  他估计就在无锡工作, 既然只关心这一点的下车扫描 件, 那这种方法是最快, 且最能解决问题的.

不过,你的思路具有一般普适性, 适用于各种情况下的,匹配..但是那个计算量和内存确实很难优化.
作者: 523066680    时间: 2021-8-8 21:07

本帖最后由 523066680 于 2021-8-8 21:08 编辑

回复 19# slimay

    我猜他后面的需求会扩充,不会只是 无锡中心。所以该建立的表还是要建。
二分没有去试,10W查询*60W条明细,三层哈希查表,调Win32::OLE接口,脚本耗时60秒。
作者: slimay    时间: 2021-8-8 21:27

本帖最后由 slimay 于 2021-8-8 21:30 编辑

回复 20# 523066680
是的,这个只要语言支持哈希, 那直接打表最省心. 貌似也没法用字典树, 这个比较的单号太长, 字典树也会爆了.
换我就直接导入mysql, 然后写个查询语句,也不用编程.这种关系到数据准确性的问题, 最好还是直接上sql.前端写个网页, 能登陆动态查询数据库,一般企业都这么搞
作者: 523066680    时间: 2021-8-8 21:38

本帖最后由 523066680 于 2021-8-8 22:19 编辑

回复 21# slimay


使用数据库比如sql server或者my sql
至少得用access
zq1210 发表于 2021-8-7 21:52


    我看到 ExcelHome 有个人说要用 Access 的时候想不至于吧,实操一顿发现:哦豁。
作者: 523066680    时间: 2021-8-8 22:20

分享一下补充了60W虚构数据的表格:
https://pan.baidu.com/s/1Yyhyl5TazZ2eKi3mfeYTJQ
提取码:23s7
作者: slimay    时间: 2021-8-8 22:25

本帖最后由 slimay 于 2021-8-8 22:27 编辑

回复 22# 523066680
http://www.code-by.org/怎么变成后花园征婚网站了
你的百度头像nice
作者: 523066680    时间: 2021-8-8 23:39

本帖最后由 523066680 于 2021-8-8 23:51 编辑

回复 24# slimay

   哇靠这么快被人抢注了。
这两年忙工作,先把内容备份了,如果有时间再重建恢复资料吧,换个域名。
以前百度博客还活着的时候,设置的头像,其实百度博客当时就是最好用的,但是不知道策划吃了什么浆糊,改到后面四不像,没人用了
作者: a20150604    时间: 2021-8-8 23:56

好多人就是要把数据库的活 硬塞在表格里折腾,折腾得不爽了,被建议塞回数据库




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2