Laravel Yajra Datatable在加载大量数据时崩溃。

huangapple go评论60阅读模式
英文:

Laravel Yajra Datatable Crashed While Loading Huge Data

问题

我在使用Laravel Yajra Datatable加载172,425条记录时遇到了问题,出现以下错误:

PHP致命错误:在vendor/laravel/framework/src/Illuminate/Database/Connection.php的第421行尝试分配4096字节时,已耗尽允许的内存大小134,217,728字节。

我已经尝试将php.ini中的内存限制从128M设置为512M,然后使用artisan命令清除缓存和配置,但什么都没有改变。

以下是我的代码:

表格

<div class="table-responsive">
    <table class="table table-striped" id="table_employee">
        <thead>
            <tr>
                <th>No</th>
                <th>Action</th>
                <th>API</th>
                <th>Description</th>
                <th>Cors</th>
                <th>Link</th>
            </tr>
        </thead>
        <thead>
            <tr>
                <th></th>
                <th></th>
                <th class="th">API</th>
                <th class="th">Description</th>
                <th class="th">Cors</th>
                <th class="th">Link</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
</div>

我的Datatable的jQuery代码

$(document).ready(function () {
    $('#table_employee').DataTable({
        processing  : true,
        serverSide  : true,
        responsive  : true,
        dom         : 'Bfrtip',
        initComplete: function() {
            this.api().columns().every(function() {
                var that = this;
                $('input', this.footer()).on('keyup change clear', function() {
                    if (that.search() !== this.value) {
                        that.search(this.value).draw();
                    }
                });
            });
        },
        ajax: "/api/getdata",
        columns: [
            {data  : 'DT_RowIndex', name  : 'DT_RowIndex'},
            {data  : 'action',      name  : 'action', orderable: false, searchable: false},
            {data  : 'API',         name  : 'API'},
            {data  : 'Description', name  : 'Description'},
            {data  : 'Cors',        name  : 'Cors'},
            {data  : 'Link',        name  : 'Link'},
        ]
    });

    $('#table_employee thead .th').each(function() {
        var title = $(this).text();
        $(this).html('<input type="text" class="form-control rounded shadow" placeholder="search" />');
    });
});

这是我的控制器:

function getdata(){
    $data = DB::table('royalti.testapi')->get();
    return DataTables::of($data)->addIndexColumn()
        ->addColumn('action', function($row){
            $btn = '<a href="javascript:void(0)" class="btn btn-info text-white btn-sm">' . $row->Cors . '</a>';
            return $btn;
        })
        ->rawColumns(['action'])
        ->make(true);
}

我使用自己的个人笔记本电脑,具有8GB的内存来运行这个程序。任何帮助都将不胜感激。

英文:

I'm having trouble using Laravel Yajra Datatable to load 172.425 record with the following error:

> PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 421.

I already tried to set my php ini memory limit from 128M to 512M then clear my cache and config using artisan command but nothing changes.

here's my code:

The Table

&lt;div class=&quot;table-responsive&quot;&gt;
        &lt;table class=&quot;table table-striped&quot; id=&quot;table_employee&quot;&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;No&lt;/th&gt;
                    &lt;th&gt;Action&lt;/th&gt;
                    &lt;th&gt;API&lt;/th&gt;
                    &lt;th&gt;Description&lt;/th&gt;
                    &lt;th&gt;Cors&lt;/th&gt;
                    &lt;th&gt;Link&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;&lt;/th&gt;
                    &lt;th&gt;&lt;/th&gt;
                    &lt;th class=&quot;th&quot;&gt;API&lt;/th&gt;
                    &lt;th class=&quot;th&quot;&gt;Description&lt;/th&gt;
                    &lt;th class=&quot;th&quot;&gt;Cors&lt;/th&gt;
                    &lt;th class=&quot;th&quot;&gt;Link&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;&lt;/tbody&gt;
        &lt;/table&gt;
    &lt;/div&gt;

My JQuery for the Datatable

$(document).ready(function () {
    $(&#39;#table_employee&#39;).DataTable({
        processing  : true,
        serverSide  : true,
        responsive  : true,
        dom         : &#39;Bfrtip&#39;,
        initComplete: function() {
            this.api().columns().every(function() {
                var that = this;

                $(&#39;input&#39;, this.footer()).on(&#39;keyup change clear&#39;, function() {
                    if (that.search() !== this.value) {
                        that.search(this.value).draw();
                    }
                });
            });
        },
        ajax: &quot;/api/getdata&quot;,
        columns: [
            {data  : &#39;DT_RowIndex&#39;, name  : &#39;DT_RowIndex&#39;},
            {data  : &#39;action&#39;,      name  : &#39;action&#39;, orderable: false, searchable: false},
            {data  : &#39;API&#39;,         name  : &#39;API&#39;        },
            {data  : &#39;Description&#39;, name  : &#39;Description&#39;},
            {data  : &#39;Cors&#39;,        name  : &#39;Cors&#39;       },
            {data  : &#39;Link&#39;,        name  : &#39;Link&#39;       },
        ]
    });

    $(&#39;#table_employee thead .th&#39;).each(function() {
            var title = $(this).text();
            $(this).html(&#39;&lt;input type=&quot;text&quot; class=&quot;form-control rounded shadow&quot; placeholder=&quot;search&quot; /&gt;&#39;);
            
        });
});

and here's my controller:

function getdata(){

    $data = DB::table(&#39;royalti.testapi&#39;)-&gt;get();

    return DataTables::of($data)-&gt;addIndexColumn()
            -&gt;addColumn(&#39;action&#39;, function($row){
                $btn = &#39;&lt;a href=&quot;javascript:void(0)&quot; class=&quot;btn btn-info text-white btn-sm&quot;&gt;&#39; . $row-&gt;Cors . &#39;&lt;/a&gt;&#39;;
                return $btn;
            })
            -&gt;rawColumns([&#39;action&#39;])
            -&gt;make(true);
}

I run this program using my own personal laptop with 8GB of RAM. Any help would be appreciated.

答案1

得分: 2

你正在使用get(),因此你的控制器首先获取所有数据,然后将数据发送到前端的yajra/datatable。

你可以这样做(在前端启用paging:true):

$model = ModelName::query();
$dt = new DataTables();
return $dt->eloquent($model)->toJson();

paging:true 仅获取用于在数据表分页上显示的数据。如果要使用数据库门面,请像这样操作:

$users = DB::table('tableName');
$dt = new DataTables();
return $dt->query($users)->toJson(); //datatables将处理其余部分
英文:

You're doing get() so your controller fetching all the data first and then sending the data into yajra/datatable on frontend.

you can do it like this(enable paging:true in dt on frontend):

$model = ModelName::query();
$dt = new DataTables();
return $dt-&gt;eloquent($model)-&gt;toJson();

paging:true fetches only data to be displayed on datatable pagination.
Do it like this for using db facades:

$users = DB::table(&#39;tableName&#39;);
$dt = new DataTables();
return $dt-&gt;query($users)-&gt;toJson(); //datatables will do the rest

答案2

得分: 1

加载所有记录并不是明智的做法。

为了提高性能,最好使用分页功能。

此外,您还可以通过减少返回的来减少数据量。

英文:

Loading all the records is not a smart thing to do

To improve the performance, it is better to use the paging feature

Also You can also reduce the amount of data by reducing the return columns

huangapple
  • 本文由 发表于 2023年3月9日 15:50:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75681735.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定