框架用的是ci,資料庫是sqlsrv(sql server 2008),sql查詢回傳的結果集有2萬個數據,我在ci框架裡面執行這個sql語句,網頁一直在轉圈,2萬個資料要轉30秒左右,但我的sql語句在sql server 2008 R2 裡面執行是秒查,在ci裡面用自帶查詢sql執行時間是200毫秒,,表示我的語句不慢。個人覺得應該是回傳數據太多導致慢的,回傳的是2萬條數據,20個欄位左右,,因為我做的是統計,要把數據導出成csv檔,所以數據比較多,這個該怎麼處理?
我的sql 語句是select * from table where create_time between 'xxxx-xx-xx 00:00:00' and 'xxxx-xx-xx 23:59:59'; 是根據時間段來的如果使用者選擇的時間範圍小那資料就少如果範圍大那資料就大數據大的時候就很慢
public function aa(){
$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();
}
這已經是最簡單的查詢了,sql語句秒查,但是用瀏覽器執行就很慢,
我在瀏覽器裡面執行, 如果查詢結果幾萬條的話瀏覽器就一直轉圈,要等四十多秒,500條足有數據是3、4秒
我在想是不是result_array()這一步 需要循環需要花費太多的時間,本身記錄就有幾萬條,然後還有二十個字段
==============2017-05-16 16:01更新===============
我沒有用ci框架自帶的result_array() ,查看ci框架文檔的時候看到一段話:
經常的,你會需要提供一個資料庫的connection ID 或是一個result ID, connection ID 可以這樣來
$this->db->conn_id;
result ID 可以從查詢傳回的結果物件取得,像這樣:
$query = $this->db->query("SOME QUERY");
$query->result_id;
於是我修改了我的程式碼拿result_id 去循環讀取每筆記錄
$sql ="select xxx";
$query=$this->db->query($sql) ;
//這裡因為我用的是sqlsrv 所以使用的是sqlsrv_fetch_array 來循環讀取每一行
//然後每讀一行就寫如csv檔
while($row=sqlsrv_fetch_array($query ->result_id,SQLSRV_FETCH_ASSOC)){
//這裡是把row 寫入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;
這樣能匯出檔但是我看了一下19204行的,16列的csv檔3M左右,需要40-45秒的時間才能匯出好,,我想問這時間還能優化的再快點嗎
這種要把所有資料匯出到excel是這樣的。資料要查出來才能寫入excel,這種我一般用後台程序導出之後發郵箱