Le framework utilise ci et la base de données est sqlsrv (sql server 2008). L'ensemble de résultats renvoyé par la requête SQL contient 20 000 éléments de données. J'exécute cette instruction SQL dans le framework ci. La page Web continue de tourner. faire pivoter 20 000 éléments de données. Cela prend environ quelques secondes, mais mon instruction SQL est exécutée en quelques secondes dans SQL Server 2008 R2. Lorsque j'utilise la requête SQL intégrée dans CI, le temps d'exécution est de 200 millisecondes, ce qui signifie que mon instruction ne l'est pas. lent. Personnellement, je pense que c'est trop lent en raison d'un trop grand nombre de données renvoyées. Il renvoie 20 000 éléments de données et environ 20 champs. Parce que je fais des statistiques et que j'exporte les données dans un fichier CSV, il y a donc beaucoup de données. Je m'occupe de ça ?
Mon instruction SQL est select * from table which create_time between 'xxxx-xx-xx 00:00:00' et 'xxxx-xx-xx 23:59:59' ; time Si la plage est petite, les données seront moindres. Si la plage est grande, les données seront volumineuses. Lorsque les données sont volumineuses, ce sera très lent.
$sql ="select * from table where create_time between 'xxxx-xx-xx 00:00:00' and 'xxxx-xx-xx 23:59:59'";
$result=$this->db->query($sql)-result_array();
}C'est déjà la requête la plus simple. L'instruction SQL peut être vérifiée en quelques secondes, mais elle est très lente à exécuter avec un navigateur
Je l'exécute dans le navigateur. Si les résultats de la requête sont des dizaines de milliers, le navigateur le fera. continuez à tourner et cela prendra quatre jours. Plus de dix secondes, 500 données suffisent, 3 ou 4 secondes
.
.
==============2017-05-16 16:01 update===============Je n'ai pas utilisé le result_array (fourni avec le framework ci), en regardant la documentation du framework ci, j'ai vu un passage :
Souvent, vous devrez fournir un ID de connexion à la base de données ou un ID de résultat. L'ID de connexion peut être comme ceci
.
$this->db->conn_id;
L'ID du résultat peut être obtenu à partir de l'objet résultat renvoyé par la requête, comme ceci :
$query = $this->db->query("SOME QUERY");
$query->result_id;
J'ai donc modifié mon code pour utiliser result_id pour lire chaque enregistrement dans une boucle$sql ="select xxx";
$query=$this->db->query($sql);
//Parce qu'ici je j'utilise sqlsrv, donc j'utilise sqlsrv_fetch_array pour lire chaque ligne dans une boucle
//Ensuite, écrivez un fichier csv après chaque ligne read
while($row=sqlsrv_fetch_array($query->result_id,SQLSRV_FETCH_ASSOC)){
// Voici le code pour écrire la ligne dans le fichier csv
}
$sql="xxx";
$query=$this->db->query($sql);
$filename= "CostDetail.csv";//导出的文件名
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'.$filename.'"');
header('Cache-Control: max-age=0');
// 打开PHP文件句柄,php://output 表示直接输出到浏览器
$fp = fopen('php://output', 'a');
// 输出Excel列名信息
$head = array(xxx);
foreach ($head as $i => $v) {
// CSV的Excel支持GBK编码,一定要转换,否则乱码
$head[$i] = iconv('utf-8', 'gbk', $v);
}
// 将数据通过fputcsv写到文件句柄
fputcsv($fp, $head);
// 计数器
$cnt = 0;
// 从数据库中获取数据,为了节省内存,不要把数据一次性读到内存,从句柄中一行一行读即可
$limit = 5000;
while ($row=sqlsrv_fetch_array($query->result_id,SQLSRV_FETCH_ASSOC)){
$cnt ++;
if ($limit == $cnt) { //刷新一下输出buffer,防止由于数据过多造成问题
ob_flush();
flush();
$cnt = 0;
}
//这里是把每个字段的编码转成gbk
$newRow[] = $this->_mb_convert_encoding($row['edis_orgsoid']);
....
unset($row);
fputcsv($fp, $newRow);
unset($newRow);
}
exit;
De cette façon, le fichier peut être exporté, mais j'ai regardé le fichier csv avec 19204 lignes et 16 colonnes, soit environ 3 Mo. L'exportation prend 40 à 45 secondes. Je veux demander si ce temps peut être optimisé plus rapidement.
Voici comment exporter toutes les données vers Excel. Les données doivent être extraites avant de pouvoir être écrites dans Excel. J'utilise généralement un processus en arrière-plan pour les exporter, puis les envoyer par e-mail
.