엑셀 10만건 디비 등록중 페이지가 ERR_TIMED_OUT 되요 채택완료
excel_file.php
excel_upload.php
그누보드/lib/PHPExcel/IOFactory.php 활용
엑셀파일 10만건
10만건 등록을 진행하면 통상 10~60분 이상도 걸립니다
즉, 브라우저가 중간에 TIME_OUT 이 발생하게 됩니다
물론 상품은 서버에서 계속 등록중입니다
phpMyAdmin 에서 SHOW PROCESSLIST; 로 확인해보면 열일중이죠
상품이 등록되는 동안 서버와 소통하면서 상황이 업데이트 되면서 이용자와 소통해야하나 고민중입니다
아래는 테스트에 필요한 요소만 최대한 정리해서 올렸습니다
아래내용을 다른 엑셀 등록에 응용하시면 나름 좋은 학습자료가 될 수 있습니다
iframe 을 넣어서 거기에 서버와 소통하는 ajax 를 만들까 하는 생각도 해보고
일단 파일이 업로드 되고, 디비에 등록 시작되면 등록중, 페이지를 닫으세요 라는 내용을 띄울까도 생각해보고
여러가지 방법을 찾아보는 중입니다
이와 관련하여 참고할 정보나 아이디어가 있다면 조언 부탁드립니다
1. 디비 테이블
item 테이블 칼럼
item_idx int(11) auto_increment
item_barcode varcha(255)
item_barcode varcha(255)
item_title varcha(255)
item_quanitiy varcha(255)
item_price varcha(255)
item_history 테이블 칼럼 item_barcode varcha(255) item_title varcha(255) item_quanitiy varcha(255) item_price varcha(255)
2. 엑셀파일 셀 정보 ( 엑셀 파일은 B1 에는 다른 행에 동일한 것이 n개 존재합니다 )
A1 = it_id 순서 B1 = BARCODE 제품번호 C1 = DESCRIPTION 상품명 D1 = QUANTITY 수량 E1 = price 금액
3. excel_file.php
$g5['title'] = '엑셀파일로 상품 대량 등록'; include_once(G5_PATH.'/head.php');
add_stylesheet('', 0); ?>
4. excel_upload.php
include_once("_common.php");
$g5['title'] = '엑셀파일로 상품 대량 등록 결과'; include_once(G5_PATH.'/head.php');
$upload_max_filesize = ini_get('upload_max_filesize');
// 업로드 허용용량 $upload_size_MB = "20"; // MB $upload_size_BY = "1048576"; // Byte $upload_size = $upload_size_MB * $upload_size_BY; //$upload_size = "20971520"; // 20MB x 1 MB x 1,048,576 bytes
$tmp_file = $_FILES['excelfile']['tmp_name']; $filesize = $_FILES['excelfile']['size']; $filename = $_FILES['excelfile']['name'];
$filename = get_safe_filename($filename);
//echo "filename = {$filename} "; //echo "upload_max_filesize = {$upload_max_filesize} "; //echo "error = {$_FILES['excelfile']['error']} ";
// 서버에 설정된 값보다 큰파일을 업로드 한다면 if ($filename) { if ($_FILES['excelfile']['error'] == 1) { $file_upload_msg .= '\"'.$filename.'\" 파일의 용량이 서버에 설정('.$upload_max_filesize.')된 값보다 크므로 업로드 할 수 없습니다.\\n'; alert($file_upload_msg); // continue; } else if ($_FILES['excelfile']['error'] != 0) { $file_upload_msg .= '\"'.$filename.'\" 파일이 정상적으로 업로드 되지 않았습니다.\\n'; alert($file_upload_msg); // continue; } }
if (is_uploaded_file($tmp_file)) { // 설정한 업로드 사이즈보다 크다면 건너뜀 if ($filesize > $upload_size) { $file_upload_msg .= '\"'.$filename.'\" 파일의 용량('.number_format($filesize).' 바이트)이 '.number_format($upload_size).' 바이트 보다 크므로 업로드 하지 않습니다.\\n'; alert($file_upload_msg); // continue; } }
add_stylesheet('', 0); include_once(G5_LIB_PATH.'/PHPExcel/IOFactory.php');
$objPHPExcel = PHPExcel_IOFactory::load($tmp_file); $sheet = $objPHPExcel->getSheet(0); // 첫번째 시트 데이타 추출
$num_rows = $sheet->getHighestRow(); $highestColumn = $sheet->getHighestColumn();
$dup_it_id = array(); $fail_it_id = array(); $dup_count = 0; $total_count = 0; $fail_count = 0; $succ_count = 0;
// 실 데이타가 2번행부터 시작되므로 $i = 2 for ($i = 2; $i <= $num_rows; $i++) { $total_count++;
$j = 0;
$rowData = $sheet->rangeToArray('A' . $i . ':' . $highestColumn . $i, NULL, TRUE, FALSE);
$it_id = addslashes($rowData[0][$j++]); // A $BARCODE = addslashes($rowData[0][$j++]); // B $DESCRIPTION = addslashes($rowData[0][$j++]); // C $QUANTITY = addslashes($rowData[0][$j++]); // D $price = addslashes($rowData[0][$j++]); // E
// 필드에 값이 있는지 확인해서 있을때만 작업시작 if ($BARCODE) { // $BARCODE 중복체크 $sql_cnt1 = " select count(*) as cnt from `item` where item_barcode = '{$BARCODE}' "; $sql_cnt1 .=" limit 1 "; //echo "sql_cnt1 = {$sql_cnt1} "; $row_cnt1 = sql_fetch($sql_cnt1); // 신규 등록일때 if($row_cnt1['cnt'] == 0) { //echo "신규 {$BARCODE} {$DESCRIPTION} "; sql_query( " insert into `item` set item_barcode = '{$BARCODE}' , item_title = '{$DESCRIPTION}' , item_quanitiy = '{$QUANTITY}' , item_price = '{$price}' "); //sql_query($sql); //echo "sql_insert = {$sql} ";
sql_query( " insert into `item_history` set item_barcode = '{$BARCODE}' , item_title = '{$DESCRIPTION}' , item_quanitiy = '{$QUANTITY}' , item_price = '{$price}' "); //sql_query($sql); //echo "sql_history = {$sql} "; $succ_count++; } else { // 중복일때 //echo "중복 {$BARCODE} {$DESCRIPTION} "; //$fail_it_id[] = $it_id; //$dup_it_id[] = $BARCODE; $dup_count++; //$fail_count++; //continue; } } } ?>
상품등록을 완료했습니다.
- 총상품수
- 완료건수
- 실패건수 0) { ?>
- 실패상품코드 0) { ?>
- 중복건수
- 중복상품코드
답변 3개
10만건을 insert하는걸 대기하는게 문제겠네요
처리방식을 좀 변경해보세요
1. 업로드
2. 브라우저에는 상태는 처리중으로 회신종료
3. 업로드된 엑셀 insert로직 작동 (서버의 배치작동으로) - 작동시작시점은 서버에서 판단하도록 설정 (시간별체크라던지...)
4. 엑셀자료 insert종료시 처리중상태를 업로드완료로 상태변경
5. 업로드된 데이타 조회가능처리
로 하면되지 않을까싶네요
insert작업중에 브라우저와의 통신을 최대한 배제 하시는게 좋습니다.
답변에 대한 댓글 1개
댓글을 작성하려면 로그인이 필요합니다.
웹브라우저 기본 타임아웃이 있기 때문에
시간이 오래걸리는 작업은 서버에서 별도 프로세스로 동작시키는게 낫습니다.
이런 경우 웹브라우저 기반으로 동작시키려면
시간이 오래걸리지 않도록 잘게 쪼개어 실행시키는 방식으로 변경하거나
별도 프로세스에서 동작시키고
진행률을 표시하거나 확인할수 있는 방법을 제공해주는 방법정도가 좋을것 같습니다.
답변에 대한 댓글 3개
각각에 대한 Insert 구문 수행보다 빠른 퍼포먼스를 보입니다.
라는 글이 보이는데, 저것에 대해서 연구해봐야겠네요.
감사합니다
데이터를 등록할 기본적인 양이 많아 버리면 별 성능향상은 기대하기 힘들것 같고
오히려 그 구문을 사용함으로 인한 설정관련 에러 대응하면서 문제해결시간도 늦어지고 해결도 제대로 안될수 있습니다.
에 한 표 추가 합니다.
댓글을 작성하려면 로그인이 필요합니다.
답변을 작성하려면 로그인이 필요합니다.
로그인
요 처리가 ... 엑셀 1열씩 처리하면서 브라우저는 계속 빈화면, 결과를 기다리는 중이 되더라구요.
화면에 다른 메시지를 뿌리는 방법을 찾아봐야겠군요
감사합니다