数据表在应用分页之前旋转并加载整个数据集


Datatables spins and loads the entire data set before pagination applies

FiddleHere

我有一个加载大量数据的表(最多 100 万行和 4-6 列(,数据不是来自数据库,而是来自 API 响应,所以我无法分解查询。

我的问题是,根据响应大小(越大,花费的时间越长(,数据表在打印整个表之前不会启动。它发生在 jsfiddle 中,有 11604 行,但你可以想象当整个 Web 应用程序围绕它并返回更多数据(比如 100,000 行(时,情况会变得多么糟糕。

处理这个问题的最佳方法是什么?我从来没有考虑过显示这么大的数据。

.JS:

$(document).ready(function() {
    $('#tableStuff').dataTable();
} );

HTML 输出:太长了,无法在此处发布

.PHP:

//$response = curl response
echo "<table class='display' id='tableStuff'>";
echo "<thead><th>Test 1</th><th>Test 2</th><th>Test 3</th><th>Test 4</th></thead>";
foreach($response as $test){
  echo "<tr><td>". $test['test1'] ."</td><td>" .$test['test2'] ."</td><td>" .$test['test3'] ."</td><td>" .$test['test4'] ."</td><tr>";
}
echo "</tbody></table>";

大型数据集会遇到几个问题:

  • 网络超时(检索结果时,将其推送到客户端等(
  • 内存占用(在 PHP 应用程序中、在客户端浏览器中等(

在客户端

一旦有几千行,就必须使用数据表库的 ajax 功能来加载数据。这样,您将加载部分数据,并保持响应的大小足够小以快速(并快速呈现(。

您可能需要通过在添加新数据段的同时卸载以前的数据段来释放一些浏览器内存。管道示例中描述了此行为的一部分,其中数据的缓存存储在客户端。通过在客户端管理此类数据存储,您可以尝试确保此数据的大小永远不会太高。

这也意味着在使用服务器端处理时,许多默认功能不再可用。 也就是说,你不能使用javascript搜索,所有的过滤内容也必须在服务器端完成(你在浏览器上没有整个数据集,这不适合大多数浏览器内存(。

在服务器(B 到 B(端

如 @Luke H 所述,您必须将结果集存储在数据库中。不能为每个客户端请求检索它。

这将导致一个新问题:

  • 您必须刷新此数据,您必须决定可以使用检索到的数据多长时间。

但你还有另外两个问题:

  • 在HTTP中请求不分页此数据的数据服务器时,您可能会遇到网络超时
  • 在PHP程序上接收此数据时,您将遇到内存问题

为了限制接收数据的内存占用,您可能需要在 cli 模式下运行 PHP(例如通过 cron(,其中默认php.ini通常允许更大的memory_limit设置。从Apache运行PHP,你不应该允许一个memory_limit=1Go,坏主意。

您还可以尝试通过管理基于文件的内存来减少内存使用量,Zend_memory等组件可用于此目的。

但首先你必须确保 curl 可以在不崩溃的情况下检索结果。

井。。。

很奇怪的是,API 服务器不管理分页。让 HTTP API 返回数百万行是 API 中的一个问题。如果对此 API 有一定的控制权,请修复它(如果可以,请使其成为服务器端数据表 API(。如果你对这个APi没有任何控制权,那么你将不得不找到正确的方法来提取小子集中的数据,将其存储在本地(小心你需要一个大数据库(,围绕它构建一个服务器端数据表API,以异步方式刷新数据(crons(,重新考虑客户端在ajax模式下工作。

这就是为什么真正的应用程序总是比演示更难构建的原因。

鉴于您使用的是PHP,那么如果可能的话,我肯定会建议您对这些数据进行分段,理想情况下,根据某些消息队列或cron进行查询,而不是在加载页面时进行查询。 这是要为网页加载的大量数据!

您可以发出 curl 请求,并将响应缓存在数据库中,然后根据 URL 参数和通过 AJAX 加载部分进行分页。

请参阅 http://www.datatables.net/manual/server-side

伪代码

<?php // The code that interacts with dataTables
// fetch from database, using pagination
$response = get_page_data($start, $count);
echo "<table class='display' id='tableStuff'>";
echo "<thead><th>Test 1</th><th>Test 2</th><th>Test 3</th><th>Test 4</th></thead>";
foreach($response as $test){
    echo "<tr><td>". $test['test1'] ."</td><td>" .$test['test2'] ."</td><td>" .$test['test3'] ."</td><td>" .$test['test4'] ."</td><tr>";
}
echo "</tbody></table>";

无论如何,我认为如果他们必须等待 100,000 个表行加载和呈现,如果他们的浏览器不只是崩溃,你会给用户带来一些挫败感。