- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在使用 php 从 mysql 数据库获取数百万条记录时遇到问题,我想将这些记录加载到 Excel 文件中。当我执行查询时,如果结果集只有很少的记录(数百条),那么它会被保存到 Excel 文件中,但是当我获取百万条记录时,它显示一个名为
的错误内部服务器错误
服务器遇到内部错误或配置错误,无法完成您的请求。请联系服务器管理员,告知错误发生的时间以及您可能执行的任何操作导致错误。
服务器错误日志中可能提供有关此错误的更多信息。
我的代码是:
<?php
/*
author: shobhan
Date: 20-10-2014
Description: This file creates excel sheet from the database based on the selection and available for download
*/
ini_set('max_execution_time', 6000);
ini_set('memory_limit','1000M');
set_time_limit(0);
//echo ini_get('memory_limit');
include("db/config.php"); //include global configuration file
global $db_host,$db_name,$db_user,$db_password; //include global variables
$con=mysqli_connect($db_host,$db_user,$db_password,$db_name);
$flag=1;
$download_filename="";
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=suburban_data.csv");
// Disable caching
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1
header("Pragma: no-cache"); // HTTP 1.0
header("Expires: 0"); // Proxies
//echo $query;
//echo "<br/><br/><br/><br/><br/><br/><br/><br/>";
$result_array=array();
$output = fopen("php://output", "w");
$headings=array("Patient Name","Mobile","Visit Date","Centre","Profiles","Gender","Age");
fputcsv($output, $headings);
function preparewhere($ptstring){
global $db_host,$db_name,$db_user,$db_password; //include global variables
global $download_filename;
global $flag;
$year=$_POST['year'];
$centre=$_POST['centre_ids'];
$gender=$_POST['gender'];
$profile=$_POST['profile_ids'];
$testresult=$_POST['testresult'];
$age=$_POST['age'];
$treatmenttype=$_POST['treatmenttype'];
$where="";
$year_condition="";
$centre_condition="";
$gender_condition="";
$test_condition="";
$testresult_condition="";
$age_condition="";
if($year=="0"){
$year_condition="Visit.VstDate >= '2013-01-01'";
}
else if($year=="2013"){
$year_condition="Visit.VstDate >= '2013-01-01' and Visit.VstDate < '2014-01-01'";
$download_filename.="2013";
}
else{
$year_condition="Visit.VstDate >= '2014-01-01'";
$download_filename.="2014";
}
//centre condition
if($centre!=0){
$centre_condition=" and centres.SysNo in(".$centre.")";
$download_filename.="_".$centre;
}
//gender condition
if($gender!="0"){
$gender_condition=" and patient.PatSex= '".$gender."'";
$download_filename.="_".$gender;
}
if($flag==2){ //if input contains only profiles
$test_condition=" and VisitProfile.ProfCode in(".$ptstring.")";
}
else{
$test_condition=" and Test.TestCode in(".$ptstring.")";
}
//test result
if($flag==1){
if($testresult!="0"){
if($testresult=="HL"){
$testresult_condition=" and (result.AbnormalFlag='H' or result.AbnormalFlag ='L')";
$download_filename.="_abnormal";
}else{
$testresult_condition=" and result.AbnormalFlag='N'";
$download_filename.="_normal";
}
}
}
//age
if($age!="0"){
if($age=="0-30")
$age_condition=" and Visit.Age>=0 and Visit.Age<=30";
else if($age=="31-40")
$age_condition=" and Visit.Age>=31 and Visit.Age<=40";
else if($age=="41-50")
$age_condition=" and Visit.Age>=41 and Visit.Age<=50";
else if($age=="51-60")
$age_condition=" and Visit.Age>=51 and Visit.Age<=60";
else
$age_condition=" and Visit.Age>60";
}
$where=$year_condition.$centre_condition.$gender_condition.$test_condition.$testresult_condition.$age_condition;
return $where;
}
//echo "where condition ".preparewhere();
//echo "<br/>";
function preparequery(){
global $flag;
$selectquery="";
if($flag==1){
$selectquery="select Distinct(patient.PatName), Visit.VstMobile, Visit.VstDate, centres.SysField, Test.TestName, patient.Patsex, Visit.Age from Visit
inner join centres on Visit.RegistrationCentreCode=centres.SysNo
inner join patient on Visit.VstPatCode=patient.Patcode
inner join result on result.TrJobCode=Visit.VstCode
inner join Test on Test.TestCode=result.TrTestCode
inner join Param on Param.ParamCode=result.TrParamCode
";
}
else{
$selectquery="select Distinct(patient.PatName), Visit.VstMobile, Visit.VstDate, centres.SysField, profiles.ProfName, patient.Patsex, Visit.Age from Visit
inner join centres on Visit.RegistrationCentreCode=centres.SysNo
inner join patient on Visit.VstPatCode=patient.Patcode
inner join VisitProfile on VisitProfile.VstCode=Visit.VstCode
inner join profiles on profiles.ProfCode=VisitProfile.ProfCode
";
}
return $selectquery;
}
function strpos_offset($needle, $haystack, $occurrence) {
// explode the haystack
$arr = explode($needle, $haystack);
// check the needle is not out of bounds
switch( $occurrence ) {
case $occurrence == 0:
return false;
case $occurrence > max(array_keys($arr)):
return false;
default:
return strlen(implode($needle, array_slice($arr, 0, $occurrence)));
}
}
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=suburban_data.csv");
// Disable caching
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1
header("Pragma: no-cache"); // HTTP 1.0
header("Expires: 0"); // Proxies
if(!mysqli_connect_errno())
{
$count=0;
$pcount=substr_count($_POST['profile_ids'], 'p'); //stores number of profiles from the string
$ptcount=substr_count($_POST['profile_ids'], ','); //stores number of tests or profiles selected
if($pcount==0)
$flag=1;
else if($pcount==$ptcount+1)
$flag=2;
else
$flag=3;
if($flag==1 || $flag ==2){ //if the selection contains either profiles or tests
//echo "profiles".$ptstring;
if($flag==1)
{
$tstring=$_POST['profile_ids'];
//echo "test".$tstring;
$mobile="";
$query_count_mobilenumbers=preparequery()." where ".preparewhere($tstring);
$con=mysqli_connect($db_host,$db_user,$db_password,$db_name);
$start = 0;
$limit = 1000;
do {
$mobile_result = mysqli_query(
$con,
$query_count_mobilenumbers." LIMIT {$start}, {$limit}",
MYSQLI_USE_RESULT // this always helps for this kind of processing (makes a smooth streaming)
);
$nbRows = 0; // cannot use mysqli_num_rows() because of `MYSQLI_USE_RESULT`
while($row = mysqli_fetch_array($mobile_result)) {
fputcsv($output, array($row[0],$row[1],$row[2],$row[3],$row[4],$row[5],$row[6]));
$nbRows ++;
}
// next batch
$start += $limit;
} while ($nbRows);
}
else{
$ptstring=str_replace("p","",$_POST['profile_ids']);
//echo "profiles are".$_POST['profile_ids'];
$query_count_mobilenumbers=preparequery()." where ".preparewhere($ptstring);
//echo "query is".$query_count_mobilenumbers;
$con=mysqli_connect($db_host,$db_user,$db_password,$db_name);
$start = 0;
$limit = 1000;
do {
$mobile_result = mysqli_query(
$con,
$query_count_mobilenumbers." LIMIT {$start}, {$limit}",
MYSQLI_USE_RESULT // this always helps for this kind of processing (makes a smooth streaming)
);
$nbRows = 0; // cannot use mysqli_num_rows() because of `MYSQLI_USE_RESULT`
while($row = mysqli_fetch_array($mobile_result)) {
fputcsv($output, array($row[0],$row[1],$row[2],$row[3],$row[4],$row[5],$row[6]));
$nbRows ++;
}
// next batch
$start += $limit;
} while ($nbRows);
}
}
else{ //if the selection contains both profiles and tests
//echo "inside both";
$no_of_profiles=substr_count($_POST['profile_ids'], 'p');
$nth_comma_index=strpos_offset(',',$_POST['profile_ids'], $no_of_profiles); //gets the nth comma's index
$pstring=str_replace("p","",substr($_POST['profile_ids'],0,$nth_comma_index));
$tstring=substr($_POST['profile_ids'],$nth_comma_index+1);
$mobile="";
$flag=1;
//query as tests
//echo "inside flag";
$query1=preparequery()." where ".preparewhere($tstring);
$con=mysqli_connect($db_host,$db_user,$db_password,$db_name);
//echo "quer".$query1;
$mobile_result1 = mysqli_query($con,$query1);
$start = 0;
$limit = 1000;
do {
$mobile_result1 = mysqli_query(
$con,
$query1." LIMIT {$start}, {$limit}",
MYSQLI_USE_RESULT // this always helps for this kind of processing (makes a smooth streaming)
);
$nbRows = 0; // cannot use mysqli_num_rows() because of `MYSQLI_USE_RESULT`
while($row = mysqli_fetch_array($mobile_result1)) {
fputcsv($output, array($row[0],$row[1],$row[2],$row[3],$row[4],$row[5],$row[6]));
$nbRows ++;
}
// next batch
$start += $limit;
} while ($nbRows);
$flag=2;
//echo "inside flag2";
$query2=preparequery()." where ".preparewhere($pstring);
$start = 0;
$limit = 1000;
do {
$mobile_result2 = mysqli_query(
$con,
$query2." LIMIT {$start}, {$limit}",
MYSQLI_USE_RESULT // this always helps for this kind of processing (makes a smooth streaming)
);
$nbRows = 0; // cannot use mysqli_num_rows() because of `MYSQLI_USE_RESULT`
while($row = mysqli_fetch_array($mobile_result2)) {
fputcsv($output, array($row[0],$row[1],$row[2],$row[3],$row[4],$row[5],$row[6]));
$nbRows ++;
}
$start += $limit;
} while ($nbRows);
}
}
else{
echo "failed to connect to database";
}
fclose($output);
?>
最佳答案
我敢打赌,您可以在服务器错误日志中找到的错误表明 PHP 脚本内存不足。发生这种情况是因为默认情况下,当从数据库服务器接收到所有行时,对数据库的查询就会完成。由于您请求了数百万行,因此结果集非常庞大,并且占用了 PHP 进程的大量内存。
我认为您应该使用MYSQLI_USE_RESULT
作为调用mysqli_query()
的第三个参数:
$mobile_result = mysqli_query($con, $query_count_mobilenumbers, MYSQLI_USE_RESULT);
这使得mysqli_query()
返回得更快(可能是在从服务器接收到结果的第一行时),并且返回的结果集仅存储接收到的行,直到它们被使用 mysqli_fetch_*()
函数进行编程。
我从未使用过 mysqli
,旧的 mysql
扩展有一个用于此目的的单独函数(称为 mysql_unbuffered_query()
),但是 >mysql
扩展已失效,所以不要使用它。
如果这种方法还是不行,那么你可以尝试使用LIMIT
从服务器批量获取数据。
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=suburban_data.csv");
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1
header("Pragma: no-cache"); // HTTP 1.0
header("Expires: 0"); // Proxies
// The next line is very important: it prevents PHP abruptly stop the script
// before it finishes what it's doing
set_time_limit(0);
$output = fopen("php://output", "w");
$headings=array("PatientName","Email","VisitDate","Centre","Profiles","Parameter","Age");
fputcsv($output, $headings);
$start = 0;
$limit = 1000;
do {
$mobile_result = mysqli_query(
$con,
$query_count_mobilenumbers." LIMIT {$start}, {$limit}",
MYSQLI_USE_RESULT // this always helps for this kind of processing (makes a smooth streaming)
);
$nbRows = 0; // cannot use mysqli_num_rows() because of `MYSQLI_USE_RESULT`
while($row = mysqli_fetch_array($mobile_result)) {
fputcsv($output, array($row[0],$row[1],$row[2],$row[3],$row[4],$row[5],$row[6]));
$nbRows ++;
}
// next batch
$start += $limit;
} while ($nbRows); // Stop when the query didn't return any row
fclose($output);
关于php - 使用php从数据库中获取数百万条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27423016/
我需要您在以下方面提供帮助。近一个月来,我一直在阅读有关任务和异步的内容。 我想尝试在一个简单的 wep api 项目中实现我新获得的知识。我有以下方法,并且它们都按预期工作: public Htt
我的可执行 jar 中有一个模板文件 (.xls)。不需要在运行时我需要为这个文件创建 100 多个副本(稍后将唯一地附加)。用于获取 jar 文件中的资源 (template.xls)。我正在使用
我在查看网站的模型代码时对原型(prototype)有疑问。我知道这对 Javascript 中的继承很有用。 在这个例子中... define([], function () { "use
影响我性能的前三项操作是: 获取滚动条 获取偏移高度 Ext.getStyle 为了解释我的应用程序中发生了什么:我有一个网格,其中有一列在每个单元格中呈现网格。当我几乎对网格的内容做任何事情时,它运
我正在使用以下函数来获取 URL 参数。 function gup(name, url) { name = name.replace(/[\[]/, '\\\[').replace(/[\]]/,
我最近一直在使用 sysctl 来做很多事情,现在我使用 HW_MACHINE_ARCH 变量。我正在使用以下代码。请注意,当我尝试获取其他变量 HW_MACHINE 时,此代码可以完美运行。我还认为
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 9 年前。 要求提供代码的问题必须表现出对所解决问题的最低限度的理解。包括尝试过的解决方案、为什么
由于使用 main-bower-files 作为使用 Gulp 的编译任务的一部分,我无法使用 node_modules 中的 webpack 来require 模块code> dir 因为我会弄乱当
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我使用 Gridlayout 在一行中放置 4 个元素。首先,我有一个 JPanel,一切正常。对于行数变大并且我必须能够向下滚动的情况,我对其进行了一些更改。现在我的 JPanel 上添加了一个 J
由于以下原因,我想将 VolumeId 的值保存在变量中: #!/usr/bin/env python import boto3 import json import argparse import
我正在将 MSAL 版本 1.x 更新为 MSAL-browser 的 Angular 。所以我正在尝试从版本 1.x 迁移到 2.X.I 能够成功替换代码并且工作正常。但是我遇到了 acquireT
我知道有很多关于此的问题,例如 Getting daily averages with pandas和 How get monthly mean in pandas using groupby但我遇到
This is the query string that I am receiving in URL. Output url: /demo/analysis/test?startDate=Sat+
我正在尝试使用 javascript 中的以下代码访问 Geoserver 层 var gkvrtWmsSource =new ol.source.ImageWMS({ u
API 需要一个包含授权代码的 header 。这就是我到目前为止所拥有的: var fullUrl = 'https://api.ecobee.com/1/thermostat?json=\{"s
如何获取文件中的最后一个字符,如果是某个字符,则删除它而不将整个文件加载到内存中? 这就是我目前所拥有的。 using (var fileStream = new FileStream("file.t
我是这个社区的新手,想出了我的第一个问题。 我正在使用 JSP,我成功地创建了 JSP-Sites,它正在使用jsp:setParameter 和 jsp:getParameter 具有单个字符串。
在回答 StoreStore reordering happens when compiling C++ for x86 @Peter Cordes 写过 For Acquire/Release se
我有一个函数,我们将其命名为 X1,它返回变量 Y。该函数在操作 .on("focusout", X1) 中使用。如何获取变量Y?执行.on后X1的结果? 最佳答案 您可以更改 Y 的范围以使其位于函
我是一名优秀的程序员,十分优秀!