Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用分页获取大量数据_C#_Mysql_Paging_Data Paging - Fatal编程技术网

C# 使用分页获取大量数据

C# 使用分页获取大量数据,c#,mysql,paging,data-paging,C#,Mysql,Paging,Data Paging,例如,假设我有一个云环境和一个客户端环境,我想将大量数据从云同步到客户端。假设我在云中有一个名为Files的db表,我希望客户机环境中存在完全相同的表 现在让我们假设几件事: 文件表非常大 文件中每一行的数据都可以随时更新,并且有一个last update列 我想获取增量,并确保在两种环境中都相同 我的解决方案: 我首先进行完全同步,将所有条目返回给客户端 我在客户端环境中保留LastSync时间,并从LastSync时间同步增量 我使用分页进行完全同步和增量同步:客户端将发出第一个请求,以获取

例如,假设我有一个
环境和一个
客户端
环境,我想将大量数据从云同步到客户端。假设我在云中有一个名为
Files
的db表,我希望客户机环境中存在完全相同的表

现在让我们假设几件事:

  • 文件表非常大
  • 文件中每一行的数据都可以随时更新,并且有一个
    last update
  • 我想获取增量,并确保在两种环境中都相同
  • 我的解决方案:

  • 我首先进行完全同步,将所有条目返回给客户端
  • 我在客户端环境中保留
    LastSync
    时间,并从
    LastSync
    时间同步增量
  • 我使用分页进行完全同步和增量同步:客户端将发出第一个请求,以获取增量的
    计数
    ,以及每个请求的
    页面大小
    所需的其他请求 例如,计数:

    SELECT COUNT(*) FROM files WHERE last_update > @LastSyncTime
    
    页面获取:

    SELECT col1, col2..
    FROM files 
    WHERE last_update > @LastSyncTime
    ORDER BY files.id
    LIMIT @LIMIT 
    OFFSET @OFFSET
    
    我的问题是:

    例如,如果第一次提取(计数)需要一段时间(例如几分钟),并且在这段时间内更新了更多的条目并将其添加到上次更新中,该怎么办

    例如:

    • 计数获取为
      最后1000秒的更新提供了100个条目
    • 获取
      计数时更新了1个条目
    • 现在,
      上一次更新1000秒
      将提供101个条目
    • 页面获取将仅从101中获取100个条目,其顺序为
      id
    • 1个条目丢失且未同步到客户端
    我尝试了另外两种选择:

    • 与上次更新的日期限制从到同步
    • last update
      排序,而不是按
      id
      列排序

    我在这两个选项中都看到了问题。

    根据数据的大小,如果它是“公共”使用的,或者可以在多个客户机之间使用,则可能有助于拆分数据。 例如,创建每日“增量”完整数据集并缓存它们。这样,数据库就不需要在第一次加载时反复查询每个客户机所需的数据

  • 尽量减少对大数据表的访问(如果数据没有任何变化,则在异地缓存)
  • 卸载和缓存经常被查询的常用数据。因此可以减少SQL查询的数量
  • last\u update
    id
    上创建一个索引应该有助于加快从数据库获取实时增量线的速度
  • 可能的解决办法:

  • 每当有新项目时,数据库每x次创建一个小时/完整集

  • 客户机在第一次从缓存中提取时获得“每日增量/每小时增量”

  • 客户端直接从数据库获取自上次增量“最新项”以来的所有项

  • 可能会有帮助:

    • 使用查询通知更新缓存:
    • 使用MySQL时
        • 不要使用
          偏移
          限制
          ;它从OK到slow再到slow。相反,通过
          last\u update
          跟踪“你离开的地方”,这样可以更高效

        • 由于datetime可以重复,所以在一次执行多少行时要灵活

        • 不断地运行这个。不要使用cron,除非用作“保持活动”

        • 不需要初始副本;此代码为您完成此操作

        • 索引(上次更新)

        代码如下:

        -- Initialize.  Note: This subtract is consistent with the later compare. 
        SELECT @left_off := MIN(last_update) - INTERVAL 1 DAY
            FROM tbl;
        
        Loop:
        
            -- Get the ending timestamp:
            SELECT @cutoff := last_update FROM tbl
                 WHERE last_update > @left_off
                 ORDER BY last_update
                 LIMIT 1  OFFSET 100;   -- assuming you decide to do 100 at a time
            -- if no result, sleep for a while, then restart
        
            -- Get all the rows through that timestamp
            -- This might be more than 100 rows
            SELECT * FROM tbl
                WHERE last_update > @left_off
                  AND last_update <= @cutoff
                ORDER BY last_update
            -- and transfer them
        
            -- prep for next iteration
            SET @left_off := @cutoff;
        
        Goto Loop
        
        ——初始化。注:此减法与后面的比较一致。
        选择@left\u off:=MIN(上次更新)-间隔1天
        来自tbl;
        循环:
        --获取结束时间戳:
        选择@cutoff:=tbl的上次更新
        上次更新>@离开时的位置
        按上次更新订购
        限制1偏移量100;——假设你决定一次做100件
        --如果没有结果,请睡眠一段时间,然后重新启动
        --通过该时间戳获取所有行
        --这可能超过100行
        从tbl中选择*
        上次更新>@离开时的位置
        
        最后一次更新你的方法涵盖了很多变通方法,你走错了方向

        开始考虑数据库复制,它将抽象所有这些解决方法,并为您提供解决此类问题的工具

        一篇关于MySQL服务器最近的组复制的优秀文章:

        但我从来没有谈到性能,我谈论的是一个关于分页的逻辑问题。我按照我写的
        last\u update
        执行所有查询(当然是索引的),但想想第一个请求,在我的情况下,第一个请求中可能有数百万行…(作为客户端,如果在最短日期(last\u update))获取数据,所以他需要同步整个表,这就是为什么我必须使用分页的原因。所以问题是关于第一次同步(或大量增量同步),你必须用分页来保护它,否则我会失败timeouts@omriman12-您有数百万行具有与上次更新完全相同的
        ?如果是这样,我们需要考虑切换到<代码> ID<代码>。如果没有,我的“页面”限制为100+(相同的上次更新值的最大数量);从第一页开始。我明白你的意思,所以如果我把它带回我的客户机-服务器示例,那么我的客户机将像我一样保留
        上次更新(即
        离开
        ),只需从服务器获取一批(例如100行),服务器将返回到cleint新的
        离开日期,等等是的,这种方法可以解决我的问题