Php導出百萬數據的優化

導出數據量很大的狀況下,生成excel的內存需求很是龐大,服務器吃不消,這個時候考慮生成csv來解決問題,cvs讀寫性能比excel高。
測試表student 數據(你們能夠腳本插入300多萬測數據。這裏只給個簡單的示例了)php

複製代碼
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `StuNo` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `StuName` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `StuAge` int(11) NULL DEFAULT NULL,
  PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, 'A001', '小明', 22);
INSERT INTO `student` VALUES (2, 'A005', '小李', 23);
INSERT INTO `student` VALUES (3, 'A007', '小紅', 24);
INSERT INTO `student` VALUES (4, 'A003', '小明', 22);
INSERT INTO `student` VALUES (5, 'A002', '小李', 23);
INSERT INTO `student` VALUES (6, 'A004', '小紅', 24);
INSERT INTO `student` VALUES (7, 'A006', '小王', 25);
INSERT INTO `student` VALUES (8, 'A008', '喬峯', 27);
INSERT INTO `student` VALUES (9, 'A009', '歐陽克', 22);
INSERT INTO `student` VALUES (10, 'A010', '老頑童', 34);
INSERT INTO `student` VALUES (11, 'A011', '黃老邪', 33);

SET FOREIGN_KEY_CHECKS = 1;
複製代碼

導出腳本export.phpmysql

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
set_time_limit(0);
ini_set ( 'memory_limit' , '128M' );
 
$fileName = date ( 'YmdHis' , time());
header( 'Content-Encoding: UTF-8' );
header( "Content-type:application/vnd.ms-excel;charset=UTF-8" );
header( 'Content-Disposition: attachment;filename="' . $fileName . '.csv"' );
//注意,數據量在大的狀況下。好比導出幾十萬到幾百萬,會出現504 Gateway Time-out,請修改php.ini的max_execution_time參數
//打開php標準輸出流以寫入追加的方式打開
$fp = fopen ( 'php://output' , 'a' );
//鏈接數據庫
$dbhost = '127.0.0.1' ;
$dbuser = 'root' ;
$dbpwd = 'root' ;
$con = mysqli_connect( $dbhost , $dbuser , $dbpwd );
if (mysqli_connect_errno())
     die ( 'connect error' );
 
$database = 'test' ; //選擇數據庫
mysqli_select_db( $con , $database );
mysqli_query( $con , "set names UTF8" ); //若是須要請設置編碼
 
//用fputcsv從數據庫中導出1百萬的數據,好比咱們每次取1萬條數據,分100步來執行
//一次性讀取1萬條數據,也能夠把$nums調小,$step相應增大。
$step = 100;
$nums = 10000;
$where = "where 1=1" ; //篩選條件,可自行添加
 
//設置標題
$title = array ( 'id' , '編號' , '姓名' , '年齡' ); //注意這裏是小寫id,不然ID命名打開會提示Excel 已經檢測到"xxx.xsl"是SYLK文件,可是不能將其加載: CSV 文或者XLS文件的前兩個字符是大寫字母"I","D"時,會發生此問題。
foreach ( $title as $key => $item )
     $title [ $key ] = iconv( "UTF-8" , "GB2312//IGNORE" , $item );
 
fputcsv ( $fp , $title );
 
for ( $s = 1; $s <= $step ; $s ++) {
     $start = ( $s - 1) * $nums ;
     $result = mysqli_query( $con , "SELECT ID,StuNo,StuName,StuAge FROM `student` " . $where . " ORDER BY `ID` LIMIT {$start},{$nums}" );
     if ( $result ) {
         while ( $row = mysqli_fetch_assoc( $result )) {
             foreach ( $row as $key => $item )
                 $row [ $key ] = iconv( "UTF-8" , "GBK" , $item ); //這裏必須轉碼,否則會亂碼
             fputcsv ( $fp , $row );
         }
         mysqli_free_result( $result ); //釋放結果集資源
         ob_flush();  //每1萬條數據就刷新緩衝區
         flush ();
     }
}
mysqli_close( $con ); //斷開鏈接

導出效果:
sql

 

 

不管從事什麼行業,只要作好兩件事就夠了,一個是你的專業、一個是你的人品,專業決定了你的存在,人品決定了你的人脈,剩下的就是堅持,用善良專業和真誠贏取更多的信任。
相關文章
相關標籤/搜索