Запрос MySQL PHPExcel занимает слишком много времени для выполнения

Я запускаю вывод PHPExcel из MySQL.

Когда я запускаю код и вывожу в Excel несколько строк вывода, все в порядке, когда я запускаю следующий код, я ничего не получаю, кроме очень длительного времени выполнения запроса в соответствии с журналами Zend Server.

Я вообще не получаю вывода, я получаю запрос на открытие файла PHP после того, что кажется вечностью!

Любая помощь приветствуется.

вот код до сих пор:

$queryGetIMEI = "SELECT DISTINCT(wi_iridium_og_device) FROM wi_iridium_og ORDER BY wi_iridium_og_device DESC";
//declare the new array for the IMEI numbers
$IMEI = array();

if ($result = $mysqli->query($queryGetIMEI)) {

    /* fetch associative array */
    while ($row = $result->fetch_array()) {
        $IMEI[] = $row["wi_iridium_og_device"];
    }
    /* free result set */
    $result->free();
}

// call the PHPexcel Files
require_once 'classes/PHPExcel.php';
require_once 'classes/PHPExcel/IOFactory.php';


$objPHPExcel = new PHPExcel();

$sheet_count = 0;


foreach ($IMEI as $c) {
    if ($sheet_count > 0) {

        // This creates the next sheet in the sequence
        // One sheet per IMEI in this example
        $objPHPExcel->createSheet();
        $objPHPExcel->setActiveSheetIndex($sheet_count);
    }

    // Add tab label to the sheet
    $objPHPExcel->getActiveSheet()->setTitle(substr($c,0,30));

    // Column headings in the first row
    $objPHPExcel->getActiveSheet()->setCellValue('A1','Device');
    $objPHPExcel->getActiveSheet()->setCellValue('B1','Site Reference');
    $objPHPExcel->getActiveSheet()->setCellValue('C1','Charge Type');
    $objPHPExcel->getActiveSheet()->setCellValue('D1','Date');
    $objPHPExcel->getActiveSheet()->setCellValue('E1','Time');
    $objPHPExcel->getActiveSheet()->setCellValue('F1','Number Called');
    $objPHPExcel->getActiveSheet()->setCellValue('G1','Service');
    $objPHPExcel->getActiveSheet()->setCellValue('H1','Call Termination');
    $objPHPExcel->getActiveSheet()->setCellValue('I1','MSISDN');
    $objPHPExcel->getActiveSheet()->setCellValue('J1','Originating Country');
    $objPHPExcel->getActiveSheet()->setCellValue('K1','UNUSED_3');
    $objPHPExcel->getActiveSheet()->setCellValue('L1','UNUSED_4');
    $objPHPExcel->getActiveSheet()->setCellValue('M1','UNUSED_5');
    $objPHPExcel->getActiveSheet()->setCellValue('N1','UNUSED_6');
    $objPHPExcel->getActiveSheet()->setCellValue('O1','UNUSED_7');
    $objPHPExcel->getActiveSheet()->setCellValue('P1','UNUSED_8');
    $objPHPExcel->getActiveSheet()->setCellValue('Q1','Units');
    $objPHPExcel->getActiveSheet()->setCellValue('R1','Currency');
    $objPHPExcel->getActiveSheet()->setCellValue('S1','Charge');

    // Dynamic data comes next
    // Query the DB based on the IMEI value. Pass the result to the while loop

    $query_GetBillPerIMEI = "SELECT SQL_NO_CACHE wi_iridium_og_device, wi_iridium_og_charge_type, wi_iridium_og_date, wi_iridium_og_time, wi_iridium_og_number_called, wi_iridium_og_service FROM wi_iridium_og WHERE wi_iridium_og_device = ". $c ." AND  wi_iridium_og.wi_iridium_og_charge_type != 'SBD Overage' ORDER BY wi_iridium_og_charge_type ASC";
    $result = $mysqli->query($query_GetBillPerIMEI);    
    $rowcount = 2;
    while ($row = $result->fetch_array()){

        $objPHPExcel->getActiveSheet()->SetCellValue('A' .$rowcount, $row['wi_iridium_og_device']);
        $objPHPExcel->getActiveSheet()->SetCellValue('B' .$rowcount, $row['wi_iridium_og_site_reference']);
        $objPHPExcel->getActiveSheet()->SetCellValue('C' .$rowcount, $row['wi_iridium_og_charge_type']);
        $objPHPExcel->getActiveSheet()->SetCellValue('D' .$rowcount, $row['wi_iridium_og_date']);
        $objPHPExcel->getActiveSheet()->SetCellValue('E' .$rowcount, $row['wi_iridium_og_time']);
        $objPHPExcel->getActiveSheet()->SetCellValue('F' .$rowcount, $row['wi_iridium_og_number_called']);
        $objPHPExcel->getActiveSheet()->SetCellValue('G' .$rowcount, $row['wi_iridium_og_service']);

Когда я добавляю следующую строку в вывод:

    $objPHPExcel->getActiveSheet()->SetCellValue('G' .$rowcount, $row['wi_iridium_og_service']);

Затем файл не запускается и не производит вывод.

У меня есть более 30 000 записей в базе данных, которые нужно запросить.

Помощь!!!


person Kris    schedule 02.09.2014    source источник
comment
Не помогает то, что вы вкладываете свои запросы: не можете ли вы использовать JOIN, чтобы выполнять только один запрос?   -  person Mark Baker    schedule 02.09.2014
comment
Используйте такие методы, как fromArray(), для заполнения данных PHPExcel, а не для заполнения каждой отдельной ячейки, или, по крайней мере, используйте свободный интерфейс, чтобы вы не вызывали getActiveSheet() для каждой отдельной ячейки.   -  person Mark Baker    schedule 02.09.2014
comment
И вы тратите впустую такие ресурсы, как память: вы повторяете курсор базы данных $result и загружаете каждую запись в память. Почему вы не работаете с данными одновременно с доступом к ним?   -  person PauloASilva    schedule 02.09.2014
comment
@PauloASilva, полностью понимаю, что ошибка связана с проблемой памяти. Как мне лучше всего переработать показанный код, чтобы не загружать все в память?   -  person Kris    schedule 02.09.2014
comment
Прежде всего старайтесь избегать обращения к базе данных для каждого IMEI (предложено @Mark Baker), затем сначала подготовьте электронную таблицу, а затем создайте ее, повторяя набор результатов базы данных.   -  person PauloASilva    schedule 02.09.2014
comment
ах, и я не смог сообщить вам, что этот запрос "SELECT SQL_NO_CACHE wi_iridium_og_device, wi_iridium_og_charge_type, wi_iridium_og_date, wi_iridium_og_time, wi_iridium_og_number_called, wi_iridium_og_service FROM wi_iridium_og WHERE wi_iridium_og_device = ". $c ." AND wi_iridium_og.wi_iridium_og_charge_type != 'SBD Overage' ORDER BY wi_iridium_og_charge_type ASC"; уязвим для SQL-инъекций   -  person PauloASilva    schedule 02.09.2014
comment
@PauloASilva, спасибо, я постараюсь переработать код, чтобы мы не повторяли его повторно. Я немного новичок в этом, наверное, самое сложное, что я делал, так что полный n00b!! :)   -  person Kris    schedule 02.09.2014
comment
@MarkBaker, спасибо, я посмотрю на функцию fromArray и попытаюсь улучшить свой код.   -  person Kris    schedule 02.09.2014
comment
@PauloASilva, Re SQL-инъекция. Как мне защититься от этого, улучшив запрос? Если да, можете ли вы привести пример лучшего кода?   -  person Kris    schedule 02.09.2014


Ответы (1)


Прежде всего прочитайте о PHP PDO и Подготовленные операторы: этого будет достаточно, чтобы справиться с SQL-инъекциями/избежать их (проблема с вашим запросом здесь WHERE wi_iridium_og_device = ". $c ." AND потому что вы не знаете значение $c, которое может быть вредным).

О том, как переработать, чтобы улучшить производительность вашего исходного кода... (это не будет работать, читайте это как псевдокод)

<?php
// call the PHPexcel Files
require_once 'classes/PHPExcel.php';
require_once 'classes/PHPExcel/IOFactory.php';

$objPHPExcel = new PHPExcel();
$sheet_count = 0;

$queryGetIMEI = "SELECT DISTINCT(wi_iridium_og_device) FROM wi_iridium_og ORDER BY wi_iridium_og_device DESC";

//declare the new array for the IMEI numbers

if ($result = $mysqli->query($queryGetIMEI))
{
    /* fetch associative array */
    while ($row = $result->fetch_array())
    {
        // your foreach login in here (without the foreach)
    }
}

Это должно улучшить объем используемой памяти, но, возможно, вы также сможете улучшить свои запросы.

person PauloASilva    schedule 02.09.2014