精华内容
下载资源
问答
  • 前端如何处理十万级别的大量数据

    千次阅读 2019-04-14 13:16:26
    这是一道面试题,刚开始面试官为我前端如何处理大量数据。我第一时间就脱口而出用分页呀!面试官说那是从后台的角度来考虑的。从前端的角度呢?emmmmm...我思考了一下,分批加载,懒加载。监听用户的滑动分批显示...

    前言

    写博客主要是用来总结、巩固知识点,加深自己对这个知识点的理解。同时希望帮助到有需要的人。如有不正确的地方。可以在评论区指出。你们的支持。是我不断进步的源泉。

    简单说明下

    这是一道面试题,刚开始面试官为我前端如何处理大量数据。我第一时间就脱口而出用分页呀!面试官说那是从后台的角度来考虑的。从前端的角度呢?emmmmm...我思考了一下,分批加载,懒加载。监听用户的滑动分批显示数据。接着又问,如果我要对这些大量数据做计算做处理呢,同时又不能让页面崩掉、假死。该如何操作呢?顿时我就懵逼了,这。。这个要怎么操作呀。心想做计算啥的不是应该在后台做完吗!

    而且怎么可能一下子给前端这么多数据吗,~~

    抱怨归抱怨,吐槽归吐槽~~

    后来问了下面试官,实现的大概思路。后来面试官说是通过worker来做子线程来实现的。

    好,那我们就来学习一下这个worker

    什么是worker

    
    运行者 Worker 接口是Web Workers API的一部分,代表一个后台任务,
    它容易被创建并向创建者发回消息。创建一个运行者只要简单的调用Worker()构造函数,指定一个脚本,在工作线程中执行。(引自MDN)
    
    复制代码

    看概念可能有点枯燥,通俗点讲就是:因为js是单线程运行的,在遇到一些需要处理大量数据的js时,可能会阻塞页面的加载,造成页面的假死。这时我们可以使用worker来开辟一个独立于主线程的子线程来进行哪些大量运算。这样就不会造成页面卡死。也说明 worker可以用来解决大量运算是造成页面卡死的问题。

    worker的语法

    
    const worker=new Worker(aURL, options)
    
    复制代码

    它有两个参数:

    aURL(必须)是一个DOMString 表示worker 将执行的脚本的URL。它必须遵守同源策略。

    options (可选)它的一个作用就是指定 Worker 的名称,用来区分多个 Worker 线程

    worker的属性

    Worker.onerror:指定 error 事件的监听函数

    Worker.onmessage:指定 message 事件的监听函数,发送过来的数据在Event.data属性中。

    Worker.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。

    worker的方法

    Worker.postMessage():向 Worker 线程发送消息。

    Worker.terminate():立即终止 Worker 线程。

    使用worker的注意点

    1.同源限制

    分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。

    2.DOM 限制

    Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。

    3.通信联系

    Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。

    4.脚本限制

    Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。

    5.文件限制

    Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

    我们来看个实列

    没有使用worker情况

    求斐波纳茨数列的第38项

     <div style="width:100px;height:100px;background-color:red;"></div>
     document.querySelector('div').onclick=function(){
        console.log('hello world');
      }
      function fibonacci(n){
        return n<2?n:arguments.callee(n-1)+arguments.callee(n-2);
       }
    console.log(fibonacci(38));
    复制代码

    使用了woroker的情况

    <div style="width:100px;height:100px;background-color:red;"></div>
     
    var worker=new Worker('worker.js');
    worker.postMessage(40);
    worker.onmessage=function(event){
        var data=event.data;
        console.log(data)
    };
    worker.onerror=function(event){
        console.log(event.fileName,event.lineo,event.message);
    };
    复制代码
    <!--worker.js-->
    self.onmessage = function (event) {
        var data = event.data;
        var ans = fibonacci(data);
        this.postMessage(ans);
    };
    
    function fibonacci(n) {
        return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2);
    }
    复制代码

    身边有电脑的小伙伴可以把上面代码复制到电脑上运行下,对比下,看下效果。就会明白这worker的作用了。

    我这里记录的可能有点粗糙,更详细的可以看下面这几篇文章(当然,我是参考这几篇文章的了)

    MDN

    Web Worker 是什么鬼?

    Web Worker 使用教程

    写的不好的地方,还请小伙伴们再评论区提出哦!

    展开全文
  • 在工作中经常遇到大量数据需要整合、去重、按照特定格式导出等情况。这篇文章主要介绍了使用 Python 处理3多条数据只要几秒钟的相关知识,需要的朋友可以参考下
  • 这两天处理后端返回得数据(数据量比较大 1天就2.3,并且我们得需求比较特殊相当于一下要画最少10得点),并且在一个画布内画多个折线图(数量不定); 问题一:可视化工具得寻找 常年使用echarts,用得比较顺手...

    这两天处理后端返回得数据(数据量比较大 1天就2.3万,并且我们得需求比较特殊相当于一下要画最少10万得点),并且在一个画布内画多个折线图(数量不定);

    问题一:可视化工具得寻找

    常年使用echarts,用得比较顺手,但是涉及到大量得数据,没有找到很好得支持(可能我没找到),这里推荐 蚂蚁数据可视化 antv G2. 可以承载大数量得数据 ,下面是链接:https://g2.antv.vision/zh/examples/area/stacked/
    在这里插入图片描述

    注:具体得这么画图这边不多叙述,直接看文档!不过这里个人建议,数据量小得 还是用echarts ,用例多,文档易懂。 G2得文档 说实话看着费劲,例子很少,百度问题得量也不多,慎用把。

    G2渲染点 最好是1000个点左右,点一万多个 几万个,渲染DOM压力太大,内存会过大导致页面卡

    问题二:数据量过大,接口请求缓慢

    数据量过大,接口一次请求肯定是不行得 太大。

    第一: 接口分页,单独获取一个数量得接口,分次请求。一次可以5000条或者其他。
    第二:数据处理,点过多得时候合并点(合并规则自己定,尽量保持在1000个点左右)。
    第三:js 代码优化,虽说js 循环千万次都是小意思,实际开发过程中,js 用在大数据循环多了,时间明显变慢,这里就得优化,能一次循环就一次循环去合并数据,像一些数据得处理可以在返回值中去循环,ajax异步得,这样也能节省时间
    第四:增加一个css等待加载数据得动画

    在这里插入图片描述

    展开全文
  • MySQL十万数据量优化实战

    千次阅读 2020-08-10 07:59:11
    这篇文章是针对MySQL中十万数据量的一些常见sql语句优化。本人作为一名准大三计科专业学生,对此理解得不深,也更没有多少实际优化经验,如有错误之处,希望各位及时指正。一,使用索引来优化SQL语句1.创建索引...

    这篇文章是针对MySQL中十万级数据量的一些常见sql语句优化。本人作为一名准大三计科专业学生,对此理解得不深,也更没有多少实际优化经验,如有错误之处,希望各位及时指正。

    也期待与各位大神的交流,这是我的联系方式:jenson_97@163.com

    以下的所有操作均以该user表为例来叙述:

    use test;
    
    create table user(
    id int primary key auto_increment comment "user表主键",
    user_id varchar(36) not null comment "用户id",
    user_name varchar(36) not null comment "用户名",
    phone varchar(20) not null comment "电话号码",
    region_id int(9) not null comment "区域id",
    )engine innodb charset utf8mb4;
    

    数据量:
    count

    一,使用索引来优化SQL语句

    1.创建索引前后执行结果对比

    在不使用索引的情况下执行该SQL

    为了使时间更真实,采用sql_no_cache来查询

    SELECT SQL_NO_CACHE id,user_id,user_name,phone,region_id FROM user WHERE user_id="58c57ebf5195488d" AND phone="15936831555" AND region_id=30;
    

    执行结果:
    result
    执行该SQL一共用掉了0.082s,即82ms

    创建复合索引后执行上面的SQL

    ALTER TABLE user ADD INDEX idx_uid_phone_regid(user_id,phone,region_id)
    

    idx
    再次执行:
    idx_select
    效果立竿见影

    2.使用复合索引的原则

    如果建立的是复合索引,那么在执行的SQL中需要保持索引的字段和个数与索引建立时的字段和个数一致
    例如:
    创建索引 idx(a,b,c)
    SQL中索引顺序:SELET * FROM table WHERE a AND b AND c;

    按照上述原则执行:

    正常

    上述SQL执行过程中使用了idx_uid_phone_regid这个索引(key字段);总共使用了3个常量来查找索引列上的值(ref字段),即user_id,phone和region_id;MySQL认为它执行查询时必须检查的行数是1行(row字段)

    如果按照其他情况执行:

    异常2
    执行该SQL过程中,MySQL使用非唯一索引或非唯一索引前缀进行的查找扫描(type字段),过程使用的索引,常量数,查找行等等可以清楚的看见。其中常量数为2,说明user_id和phone字段均用到了索引。
    异常1
    可见,执行该SQL过程中,MySQL对全表进行了扫描(type字段);过程没有使用任何索引(key字段);常量数为0,说明phone与region_id都没有使用索引;MySQL认为他执行查找是必须查找的行数是252241(rows字段)。

    我举一个例子说明这种情况:
    将文章开头所建的索引视为一座桥,查询过程就是从桥的一头到另一头,其中user_id为桥头,phone为桥身,region_id为桥尾。在使用三个索引时,就相当于在两地搭建了一座完整的桥,非常快就可以到河对面;如果使用user_id和phone就相当于与只有桥头和桥身,速度相对较慢;如果只使用region_id,那你就规矩的游过去吧。

    (如果有对explain命令不清楚的朋友,请移步查阅)

    二,杜绝对索引使用计算,转型等处理

    以下用法会导致索引失效

    1. 计算,比如+ - * / != <> or等等
    2. 函数,如sum(),round()等等
    3. 手动/自动类型转化,如:id=“1” ,本来是数字,却将他转化为字符串(5.7以上不存在该问题)

    我就以其中的几种情况说明:
    异常4
    所用到的联接类型为index,说明除了索引树被扫描之外其他都与ALL类型相同,理论查询的行数为252241行
    异常3
    现在,我使用OR来查询该字段,explain给出的反馈是:MySQL查询过程没有使用任何索引,且对全表进行了扫描。

    三,索引不要放在范围查询的右边

    比如复合索引:idx(x,y),当where x > 1 and y = “”,这时只能用到x,y字段用不到索引。
    下边是测试结果:
    在这里插入图片描述

    四,杜绝SELECT *的使用

    1,数据库知道 * 表示所有,查数据时会增大开销(记录数据库和应用程序元数据的目录)
    2,多出一些不用的列,这些列可能正好不在索引的范围之内(索引的好处不再多说)select * 杜绝了索引覆盖的可能性,而索引覆盖又是速度极快,效率极高荐的查询方式。
    3,不需要的字段会增加数据传输的时间,即使 MySQL 服务器和客户端是在同一台机器上,使用的协议还是 tcp,通信也是需要额外的时间。
    4,大字段,例如很长的 varchar,blob,text。准确来说,长度超过 728 字节的时候,会把超出的数据放到另外一个地方,因此读取这条记录会增加一次 I/O 操作。
    5,影响数据库自动重写优化SQL(类似 Java 中编译 class 时的编译器自动优化) 。----Oracle
    6,select * 数据库需要解析更多的 对象,字段,权限,属性相关,在 SQL 语句复杂,硬解析较多的情况下,会对数据库造成沉重的负担
    7,额外的I/O,内存和 CPU 的消耗,因为多取了不必要的列。
    8,用 SELECT * 需谨慎,因为一旦列的个数或顺序更改,就有可能程序执行失败

    四,在使用order by时,要注意索引的有序性

    order by最后的字段是复合索引的一部分,并且放在索引组合顺序的最后,避免出现file_sort的情况,影响查询性能。
    例如:idx(a,b,c)
    where a="" and b="" order by c

    正常情况下

    在这里插入图片描述
    可见:user_id和phone均使用到了索引

    非正常情况下

    在这里插入图片描述
    在查询过程,仅仅user_id使用到了索引。

    除了上述常见的一些优化手段之外,还有其他许多优化手段,待后续整理。

    参考资料:
    1.《阿里巴巴开发手册》
    2. https://www.jianshu.com/p/2ffd8d806109

    展开全文
  • 本文实例分析了php查询mysql大量数据造成内存不足的解决方法。分享给大家供大家参考。具体分析如下: 一、问题 使用php查询mysql大数据量的时候,程序尚未执行完毕,跳出警告: Fatal error: Allowed memory size ...
  • 多线程处理大量数据 java

    千次阅读 2020-09-27 17:12:11
    例如:获取大量数据并处理,生成execl文件导出 问题描述: 5W条数据处理后生成execl文件需要6个小时,效率慢 APP 中接收数据代码: @Override public void run() { bytes = mmInStream.read(buffer); mHandler....

    项目场景:

    简述项目相关背景:
    例如:获取大量数据并处理,生成execl文件导出


    问题描述:

    5W条数据处理后生成execl文件需要6个小时,效率慢 APP 中接收数据代码:
    @Override
            public void run() {
                bytes = mmInStream.read(buffer);
                mHandler.obtainMessage(READ_DATA, bytes, -1, buffer).sendToTarget();
            }
    

    原因分析:

    数据量太多


    解决方案:

    使用多线程批量处理数据,下面是线程类,直接复制即可

    package com.wwhl.cms.service.impl;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.*;
    
    /**
     * @param <H> 为被处理的数据类型
     * @param <T>返回数据类型
     */
    public abstract class MultiThread<H,T>{
        private final ExecutorService exec; //线程池
        private final BlockingQueue<Future<T>> queue = new LinkedBlockingQueue<>();
        private final CountDownLatch startLock = new CountDownLatch(1); //启动门,当所有线程就绪时调用countDown
        private final CountDownLatch endLock; //结束门
        private final List<H> listData;//被处理的数据
    
    
        /**
         * @param list list.size()为多少个线程处理,list里面的H为被处理的数据
         */
        public MultiThread(List<H> list){
            if(list!=null&&list.size()>0){
                this.listData = list;
                exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); //创建线程池,线程池共有nThread个线程
                endLock = new CountDownLatch(list.size());  //设置结束门计数器,当一个线程结束时调用countDown
            }else{
                listData = null;
                exec = null;
                endLock = null;
            }
        }
    
        /**
         *
         * @return 获取每个线程处理结速的数组
         * @throws InterruptedException
         * @throws ExecutionException
         */
        public List<T> getResult() throws InterruptedException, ExecutionException{
            List<T> resultList = new ArrayList<>();
            if(listData!=null&&listData.size()>0){
                int nThread = listData.size(); //线程数量
                for(int i = 0; i < nThread; i++){
                    H data = listData.get(i);
                    Future<T> future = exec.submit(new Task(i,data){
                        @Override
                        public T execute(int currentThread,H data) {
                            return outExecute(currentThread,data);
                        }
                    }); //将任务提交到线程池
                    queue.add(future); //将Future实例添加至队列
                }
                startLock.countDown(); //所有任务添加完毕,启动门计数器减1,这时计数器为0,所有添加的任务开始执行
                endLock.await(); //主线程阻塞,直到所有线程执行完成
                for(Future<T> future : queue) {
                    resultList.add(future.get());
                }
                exec.shutdown(); //关闭线程池
            }
            return resultList;
        }
        /**
         * 每一个线程执行的功能,需要调用者来实现
         * @param currentThread 线程号
         * @param data 每个线程被处理的数据
         * @return T返回对象
         */
        public abstract T outExecute(int currentThread,H data);
    
        /**
         * 线程类
         */
        private abstract class Task implements Callable<T>{
            private int currentThread;//当前线程号
            private H data;
            public Task(int currentThread,H data){
                this.currentThread=currentThread;
                this.data=data;
            }
            @Override
            public T call() throws Exception {
                startLock.await(); //线程启动后调用await,当前线程阻塞,只有启动门计数器为0时当前线程才会往下执行
                T t =null;
                try{
                    t = execute(currentThread,data);
                }finally{
                    endLock.countDown(); //线程执行完毕,结束门计数器减1
                }
                return t;
            }
    
            /**
             * 每一个线程执行的功能
             * @param currentThread 线程号
             * @param data 每个线程被处理的数据
             * @return T返回对象
             */
            public abstract T execute(int currentThread,H data);
        }
    }
    
    

    使用多线程批量处理数据使用场景:

     /**
         * 分割list集合
         *
         * @param dataList
         * @return
         */
        public List<Card> subList(List<Card> dataList) {
            List<Card> resultlist = new ArrayList<>();//存放批量数据处理的总结果集
            if (null != dataList && dataList.size() > 0) {
                int pointsDataLimit = 10;//限制条数 10条一批  也是线程池线程数量
                Integer size = dataList.size();
                //判断是否有必要分批
                if (pointsDataLimit < size) {//大于10条
                    int part = size / pointsDataLimit;//分批数
                    for (int i = 0; i < part; i++) {
                        List<Card> listPage = dataList.subList(0, pointsDataLimit);  //10条数据
                        Integer start = cardlist.size();//10条数据在总结果集的开始下标
                        cardlist = testTime(listPage, resultlist );//返回拼接后的总结果集
                        Integer end = resultlist .size();//10条数据在总结果集的结束下标
                        for (i = start; i < end; i++) {
                       //对总数据集的10条数据进行业务处理
                        }
                        //剔除已经处理过的10条数据
                        dataList.subList(0, pointsDataLimit).clear();
                    }
                    if (!dataList.isEmpty()) {//小于10条
                        cardlist = testTime(dataList, cardlist);//处理最后的数据
                    }
                } else {
                }
            }
    
            return resultlist ;
        }
    
     /**
         * 多线程处理批量数据
         *
         * @param splitList 处理数据
         * @param cardlist  处理后总数据
         *
         * @return
         */
        public List<Card> testTime(List<Card> splitList, List<Card> cardlistr) {
            List<Card> list = null;
            try {
                MultiThread<Card, Card> multiThread = new MultiThread<Card, Card>(splitList) {              
                    @Override
                    public Card outExecute(int currentThread, Card data) {
                    //业务处理
                       /* String iccid = data.getIccid();
                        String allOrder = cardServerService.findAllOrder(iccid);
                        String allFlow = cardServerService.allFlowByiccid(iccid);
                        String allUseFlow = cardServerService.allUseFlowByiccid(iccid);
                        Card card = cardMapper.findByIccid(iccid);
                        String monthFlow = card.getMonthFlow();
                        data.setMonthFlow(monthFlow);
                        data.setAllOrder(allOrder);
                        data.setAllFlow(allFlow);
                        data.setAllUseFlow(allUseFlow);
                        return data;*/
                    //业务处理end
                    }
                };
                list = multiThread.getResult();//返回结果
                for (Card ccar : list) {
                    cardlist.add(ccar);//批量数据遍历放入总结果
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return cardlist;
    
        }
    
    展开全文
  • List<UserModel> userModels = UserModelRespository.findByRegisteredAndCreateTimeLessThan("1",start);...其中通过数据库查询出来的userModels会有几十万数据,用foreach遍历的话会有什么影响,有什么解决办法
  • Java多线程处理大量数据

    万次阅读 2017-04-18 22:21:10
    并发环境是非常复杂的,什么情况都有可能发生,Java给我们提供了线程调度以及同步等机制来保证多线程环境下我们的代码依然可以正确执行,下面是多个线程处理大量数据的简单实现,入门级import java.util.ArrayList;...
  • Python使用Pandas处理大量数据

    千次阅读 2019-10-21 07:28:57
    最近接到一个需求是把近100G的CSV数据(多个目录的多个文件,单文件最大1G,每个目录下是同一类目的数据,类目数据需要做排重处理)导入Mysql 环境:桌面笔记本电脑,i5+8G(约2G可用内存)+128GSSD+1T+Win10 实现...
  • java大数据处理-大量数据到Excel

    千次阅读 2015-12-31 16:06:42
     在Java Web开发中,经常需要导出大量数据到Excel,使用POI、JXL直接生成Excel,很容易就造成内存溢出了。  1、有一种方式,就是把数据写成csv格式文件。  1)csv文件可以直接用Excel打开。  2)写csv文件的...
  • 前段时间有朋友问我一个他们公司遇到的问题, 说是后端由于某种原因没有实现分页功能, 所以一次性返回了2数据,让前端用 select 组件展示到用户界面里. 我听完之后立马明白了他的困惑, 如果通过硬编码的方式去直接...
  • POI3.8版本之前的版本处理大量数据的导出Excel效果不是很理想,主要在与Excel2003版本单个Sheet的行限制为65536,大量数据的导出得分多个Sheet,针对这一点,客户就不会满意。其次,在实验过程中,大数据量的导出很...
  • 此方式是将excel数据读取以List&lt;String[]&gt; 形式存放,需要传入excel文件路径,sheetName,excel列数,其中excel列数需要与excel列数一致 package pdata; /* ======================================...
  • 点击上方“AI公园”,关注公众号,选择加“星标“或“置顶”作者:Admond Lee编译:ronghuaiyang前戏我们用Pandas来处理大量数据,而不是大数据,为什...
  • httpclient最近在单记录大量传输数据的时候出现了问题,由于是大量数据的单条传输(业务需要),所以出现服务器的连接被占满拒绝的连接的情况;  这里我在httpclient请求的时候部分代码是这样写的; HttpClient client ...
  • (一共要处理50w条数据) (这是几千条后打印的时间: 构造Athlete ::= ,8990,GER,38,9.46>时间:777ms 构造Athlete ::= ,8991,IND,32,9.42>时间:728ms 构造Athlete ::= ,8992,GER,29,9.23>时间:444ms...
  • 1. 数据量达到N行(例如:100行的时候)就往磁盘中写数据(就是将结果先写到磁盘的导入文件中,最后直接导出) 思考:前端直接导出这么大的文件,能导出吗? 实现方案:POI 解决写入excel内存溢出 POI写入excel...
  • 在实际数据处理应用中,经常使用Excel的数据复制,黏贴,常用的方法就是通过在Excel里通过直接拖拉鼠标来进行复制,黏贴,该文针对于百万级别数据的选中,复制,以及函数功能的复制,要远远方便于鼠标的无线长时间的...
  • VC++ 下对大量实时数据的采集处理,有环形缓冲区的思想啊,可以读读。
  • excle大量数据读取

    2010-07-01 10:01:41
    excle大量数据读取,10条数据没有问题,一般的方法很可能出现内存溢出
  • 如何使QTreeView快速显示1000数据,并且内存占用少呢?这个问题困扰我很久,在网上找了好多相关资料,都没有找到合理的解决方案,今天在这里把我的解决方案提供给朋友们,供大家相互学习。 我开始使用的...
  • (2)假设用户日均1条流水,也就是说日增流水数据量在100W级别,月新增流水在3kW级别,3个月流水数据量在亿级别;常见解决方案:用一个定时任务,每个月的第一天计算一次。 //(1)查询出所有用户 uids[] = select...
  • mysql大数据量处理

    千次阅读 2019-05-11 09:28:52
    一、概述 分表是个目前算是比较炒的比较流行的概念,特别是在大负载的情况下,分表是一个良好分散数据库压力的好方法... 按照分析结果进行数据的提取或者修改 --> 返回处理结果 当然,这个流程图不一定正确,这只...
  • 数据量的五种处理方式

    万次阅读 2018-09-19 17:02:01
    处理海量数据问题,无非就是: 分而治之/hash映射 + hash统计 + 堆/快速/归并排序; Bloom filter/Bitmap; Trie树/数据库/倒排索引; 外排序; 分布式处理之hadoop/mapreduce。 本文接下...
  • 十万级别Excel数据的导入导出

    千次阅读 2019-06-19 16:57:52
    导入:使用Excel Streaming Reader进行海量数据读取 这个第三方工具会把一部分的行(可以设置)缓存到内存中,在迭代时不断加载行到内存中,而不是一次性的加载所有记录到内存,这样就可以不断的读取excel内容并且不...
  • 在excel的一个sheet中导出大批量数据大于20,仅需几秒。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 147,673
精华内容 59,069
关键字:

十万数据量怎么处理