Data yang dikembalikan oleh pertanyaan php terlalu besar dan mengimport fail csv adalah sangat perlahan.
怪我咯
怪我咯 2017-05-17 09:55:57
0
2
707

Rangka kerja menggunakan ci dan pangkalan data adalah sqlsrv (sql server 2008 Set hasil yang dikembalikan oleh pertanyaan sql mempunyai 20,000 keping data Saya melaksanakan pernyataan sql ini dalam rangka kerja ci putarkan 20,000 keping data Ia kira-kira beberapa saat, tetapi pernyataan SQL saya dilaksanakan dalam beberapa saat dalam SQL Server 2008 R2 Apabila saya menggunakan SQL pertanyaan terbina dalam dalam CI, masa pelaksanaan ialah 200 milisaat, yang bermaksud bahawa pernyataan saya tidak. lambat. Secara peribadi, saya fikir ia terlalu perlahan kerana terlalu banyak data yang dikembalikan. Data yang dikembalikan ialah 20,000 keping data dengan kira-kira 20 medan Kerana saya sedang melakukan statistik dan mengeksport data ke dalam fail csv, jadi terdapat banyak data. Bagaimana saya harus menangani ini?
Pernyataan sql saya adalah pilih * dari jadual di mana create_time antara 'xxxx-xx-xx 00:00:00' dan 'xxxx-xx-xx 23:59:59'; Ia adalah berdasarkan tempoh masa jika pengguna memilih masa Jika julat kecil, data akan kurang Jika julat besar, data akan besar Apabila data besar, ia akan menjadi sangat perlahan

fungsi awam 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();

}. terus berputar dan ia akan mengambil masa lebih daripada sepuluh saat, 500 keping data sudah memadai, 3 atau 4 saat


Saya tertanya-tanya sama ada langkah result_array() perlu digelung dan mengambil masa terlalu lama. Terdapat berpuluh-puluh ribu rekod dan terdapat dua puluh medan

==============2017-05-16 16:01 kemas kini===============

Saya tidak menggunakan result_array( yang disertakan bersama rangka kerja ci ), apabila melihat dokumentasi rangka kerja ci, saya melihat petikan:

Selalunya, anda perlu memberikan ID sambungan pangkalan data atau ID hasil ID sambungan boleh menjadi seperti ini
$this->db->conn_id;

ID keputusan boleh diperolehi daripada objek hasil yang dikembalikan oleh pertanyaan, seperti ini:

$query = $this->db->query("SOME QUERY");
$query->result_id;

Jadi saya mengubah suai kod saya untuk menggunakan result_id untuk membaca setiap rekod dalam gelung

$sql ="select xxx";

$query=$this->db->query($sql);

//Ini kerana Saya menggunakan sqlsrv, jadi saya menggunakan sqlsrv_fetch_array untuk membaca setiap baris dalam gelung

//Kemudian tulis fail csv selepas setiap baris dibaca
while($row=sqlsrv_fetch_array($query->result_id,SQLSRV_FETCH_ASSOC)//Di Sini
ialah kod untuk menulis baris ke dalam fail csv
}

Kod khusus ada di bawah

$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;

Dengan cara ini fail boleh dieksport, tetapi saya melihat fail csv dengan 19204 baris dan 16 lajur, iaitu kira-kira 3M Ia mengambil masa 40-45 saat untuk mengeksport. Saya ingin bertanya sama ada kali ini boleh dioptimumkan dengan lebih pantas
怪我咯
怪我咯

走同样的路,发现不同的人生

membalas semua(2)
大家讲道理

Ini adalah cara untuk mengeksport semua data ke kecemerlangan. Data tersebut perlu disemak sebelum ia boleh ditulis ke dalam excel Saya biasanya menggunakan proses latar belakang untuk mengeksportnya dan kemudian menghantarnya ke e-mel

给我你的怀抱

Berikan beberapa idea:

  • Bahagian hadapan harus mempunyai beberapa julat masa untuk dipilih daripada bahagian belakang menjalankan tugas mengikut julat masa ini untuk mendapatkan pangkalan data dan meletakkannya pada pelayan sebagai fail statik dan mengikat medan yang diubah suai

  • Setiap kali jadual ditambah, dipadam atau diubah suai, tugas kemas kini berjadual akan dicetuskan;

  • Setiap kali anda mengeksport, melalui perbandingan
  • , jika ia adalah sama, anda boleh mengambil fail statik yang telah dieksport sebelum ini Jika ia tidak sama, anda perlu mengemas kininya di tempat, tetapi keadaan ini sepatutnya agak jarang berlaku ;

    timemodified

  • Operasi pengambilan data dari pangkalan data ini tidak akan menjejaskan penggunaan pelanggan saya harap ia dapat membantu anda
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!