由于我的数据库有大量数据,我的代码需要花费大量时间才能执行。最初当有5000行时它工作正常,但现在我的数据增加了,加载大约需要2分钟。我的PHP代码是:
$result=$db->query("SELECT DateLastSaved,MDid,FileName FROM InitialLog");
$filesarray=array();
$datearray=array();
while($row3=mysqli_fetch_array($result))
{
$tobestored=$row3['MDid']."||".$row3['FileName'];
$key=array_search($tobestored,$filesarray);
$date=$row3['DateLastSaved'];
if(!is_numeric($key))
{
$filesarray[]=$tobestored;
$datearray[]=$date;
}
else
{
$aryear=date("Y",strtotime($datearray[$key]));
$armonth=date("m",strtotime($datearray[$key]));
$arday=date("d",strtotime($datearray[$key]));
$pryear=date("Y",strtotime($date));
$prmonth=date("m",strtotime($date));
$prday=date("d",strtotime($date));
if($aryear==$pryear && $armonth==$prmonth)
{
if($prday>$arday)
{
$datearray[$key]=$date;
}
}
}
}
数组在此代码中花费了大量时间。
(来自评论)。我的目的是获取每个MD的所有文件名以及最后保存日期。如果从列表中重复出现一个特定的文件并在1月,2月等等存在,我希望该文件仅从1月开始,也就是最早的月份,也是那个月我想要的那个月的最后一个文件,即if它存在于1月1日,1月2日,1月30日,我想获得1月30日的一个。
答案 0 :(得分:3)
尝试使用HashMap
在php术语中,它是简单的关联数组。
$key=$row3['MDid']."||".$row3['FileName'];
$date=$row3['DateLastSaved'];
if(!isset($datearray[$key]))
{
$datearray[$key]=$date;
}
else
{
...
}
它具有恒定的密钥搜索时间,应该非常适合您尝试解决的任务。
答案 1 :(得分:1)
您可以在查询中使用LIMIT并使用分页获取结果来缩短页面加载时间。因此,所有记录都不会出现在单个结果集中,但这可以通过分页
实现SELECT DateLastSaved,MDid,FileName FROM InitialLog WHERE FileName NOT LIKE '%Patient Names%' LIMIT $offset $perpage
此处$offset
是结果的索引号(page_number * $ perpage),$perpage
是您要在单个查询中获取的行数。
答案 2 :(得分:1)
您的说明(在对您的问题的评论中提出)是:
MDid
的每个不同值 - ... 专业提示:尝试在开始编写代码之前尽可能清楚地制定此类规范。规格越细,清晰度就越重要。这个规格有头发。
让我们将其构建为MySQL查询。首先,您需要找到每个MDid
出现的第一个月。此子查询使用LAST_DAY()
执行此操作。在此应用程序中,将LAST_DAY(date)
视为含义MONTH_AND_YEAR_OF(date)
。
SELECT MDid, MIN(LAST_DAY(DateLastSaved)) FirstMonth
FROM InitialLog
GROUP BY MDid
这个聚合子查询每个医生产生一行,其中第一个月的最后一天。 (这就是MIN(LAST_DAY(DateLastSaved))
所做的。)
专业提示:很多人发现在phpMyAdmin或其他命令行SQL程序中测试子查询很有帮助。
现在让我们在另一个子查询中使用它来查找表中第一个月发生的最新日期。
SELECT MAX(DateLastSaved) LastInMonth,
a.MDid
FROM InitialLog a
JOIN (
SELECT MDid, MIN(LAST_DAY(DateLastSaved)) FirstMonth
FROM InitialLog
GROUP BY MDid
) b ON a.MDid = b.MDid
AND LAST_DAY(a.DateLastSaved) = b.FirstMonth
GROUP BY a.MDid
这里我们将InitialLog
表连接到第一个子查询,使用ON
子句消除第一个月内没有InitialLog
的所有行(这就是{{1} 1}}确实)。
冷却。这个子查询为我们提供了每个医生在您的规范中的日期。最后,我们必须获取包含LAST_DAY(a.DateLastSaved) = b.FirstMonth
以及其他列的原始行。我们已经知道FileName
和MDid
。
这是最终查询。
DateLastSaved
这为每个MDid提供一行。它使用DBMS来实现您的规范,而不是查看表的所有行。如果您的表格上有SELECT orig.DateLastSaved, orig.MDid, orig.FileName
FROM InitialLog orig
JOIN ( /* that subquery */
) datechoice ON orig.MDid = datechoice.MDid
AND orig.DateLastSaved = datechoice.LastInMonth
ORDER BY orig.MDid /* or whatever order you want */
的索引,那么当您的桌子中有数万名医生和数十年的数据时,此查询可能会非常好地扩展。
总而言之,你的php程序就是这样。现在您可能会猜到为什么它被称为结构化查询语言。
(MDid, DateLastSaved)
答案 3 :(得分:0)
首先我想你会说你想要获得最新的' DateLastSaved'对于每个' MDid'和' FileName'组合
如果是这样,我只需将SQL改为
SELECT concat(MDid, FileName) tobestored,
max(DateLastSaved) maxDateLastSaved
FROM InitialLog
GROUP BY 1
此查询每个' MDid'和' FileName'包含组合值和最近日期的组合。
不再需要遍历所有提取的记录来搜索数组键或比较日期。
我唯一不确定的是这部分
if($aryear==$pryear && $armonth==$prmonth) {
if($prday>$arday) {
$datearray[$key]=$date;
}
}
看起来你想保留旧的' DateLastSaved'如果它来自前一个月或一年。 如果这适用,我对您的查询的更改不会提供您想要的数据。