DataTable серверная сторона, обрабатывающая большой ответ данных, терпит неудачу на более чем 2500 записях или около того - PullRequest
0 голосов
/ 10 ноября 2018

Необходимо отобразить большой объем данных в DataTable на странице Drupal.Я использую обработку на стороне сервера.Файл php возвращает массив json.Это работает (но очень медленно) до 2500 записей.Более того, ответ не получится.Кроме того, когда я добавляю некоторые значки вместо текстовых ссылок в массив json (см. Код php ниже), чтобы они отображались в таблице рядом с данными заказчика, количество записей, с которыми работает DataTable, уменьшается примерно до 800.

Может ли это быть из-за размера массива json?

Как вывести на экран около 5000 записей в DataTable и убедиться, что он продолжает работать по мере роста данных?Как оптимизировать все это, чтобы ускорить его?

JavaScript:

var oTable = $('#mytable').DataTable({
  ajax: "ajax/myphp.php?i="+i+"&a=",
  scrollY: 600,
  scroller: {
    loadingIndicator: true
    },
  paging:   false
 });

Вот что происходит в файле myphp.php:

<?php
    include '../includes/functions/config.php';
    include '../includes/functions/functions.php';

    if(isset($_GET)){
    $i=$_GET['i'];
    $a=$_GET['a'];
    }

    $output= array();

    $sql= "Select * from customers where a= $a and i=$i"; //returns about 2600-5500 records depends on the filtering, takes about 0.0010 seconds. If I limit the query to 2500 everything works fine.

     /*
    get query results
    loop thought the result
    for each record 
       - get first, last name, address, phone, email. 
       - add few links like View, Edit, Payments, Files
       - run 2 small functions with a quick db query in each to get things like 
         balance
    */

    $num= mysql_num_rows($data);

    while($row= mysql_fetch_assoc($data)){
        //do what I mentioned above
        $links.= "<a href='edit_customer.php?id=".$row['id']."'>Edit</a>  "; //I add about 5 similar links to each record
        $output[]= [$row['Last'], $row['First'], $row['Date'],$row['Phone'], $row['Email'], $links];
    }


    $json_data = array(
                "draw"            =>1,
                "recordsTotal"    => $num,
                "recordsFiltered" =>$num,
                "data"            => $output
                );


    echo json_encode($json_data);

Спасибо!

1 Ответ

0 голосов
/ 10 ноября 2018

Ваша проблема здесь, когда вы пишете: «Запустите 2 маленькие функции с быстрым запросом БД в каждой, чтобы получить такие вещи, как баланс».

Помещение последующего вызова MySQL в цикл, как правило, является плохой идеей, и оно приведет к экспоненциальному увеличению времени отклика в зависимости от объема данных, которые вы получаете. Вместо этого вы должны попытаться получить как можно больше данных за одно соединение с базой данных или минимизировать количество обращений к базе данных. Обычно вы можете многого добиться, используя JOIN, что-то вроде:

SELECT
    c.*,
    b.*
FROM
    customers as c
LEFT OUTER JOIN
    balance as b
    ON b.customerId = c.id
    /* You can also add other join logic in here to control the data coming back */
WHERE
    c.a = ?
AND c.i = ?;

Каждый раз, когда вы запускаете запрос через MySQLi, вы устанавливаете новое соединение с базой данных (которое включает в себя рукопожатие серверов), передаете запрос, ожидаете, пока MySQL обработает запрос, ожидаете, пока сервер MySQL вернет данные, затем закрыть соединение, прежде чем двигаться дальше Если вы сделаете это дважды для каждой записи в вашем результате с 2500 записями, вы столкнетесь с большим количеством накладных расходов - установление и закрытие 5001 соединения из одного скрипта! Присоединение ваших таблиц к первоначальному запросу устраняет все эти дополнительные издержки и возвращает их к одному вызову базы данных. Вы входите, вы получаете все данные, которые вам нужны, и вы возвращаетесь - и это единственное место, где реляционные базы данных, такие как MySQL, действительно сияют.

Подробнее о присоединении таблиц см. Здесь: https://dev.mysql.com/doc/refman/8.0/en/join.html

Примечание: я переключил объявления прямой строки для параметров. Очень плохая идея (TM) - помещать параметры URL непосредственно в MySQL, поскольку это может привести к так называемому внедрению MySQL, когда кто-то может украсть ваши данные и нанести ущерб вашим структурам данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...