Php 使用for循环的性能MySQL查询

Php 使用for循环的性能MySQL查询,php,mysql,performance,phalcon,Php,Mysql,Performance,Phalcon,在这种方法中,首先我必须得到两个日期之间的星期日日期,在这种情况下大约1年。然后我在for循环中遍历这些日期,并将它们设置为查询。我使用事先准备好的语句来加快速度 //Get the first day and last day $dateInitial = strtotime('2018-08-21'); $dateFinal = strtotime('2019-08-21'); $final = array(); $sql = "SELECT id_product, pro

在这种方法中,首先我必须得到两个日期之间的星期日日期,在这种情况下大约1年。然后我在for循环中遍历这些日期,并将它们设置为查询。我使用事先准备好的语句来加快速度

//Get the first day and last day
$dateInitial = strtotime('2018-08-21');
$dateFinal   = strtotime('2019-08-21');
$final       = array();

$sql = "SELECT id_product, product, plant_sowing, plant_production, area_planting, CONCAT(id_product,'_', weeks) AS identity
              FROM (
                    SELECT sw_sowing.id_product, pr_products.product, sw_sowing.type, YEARWEEK(:dates,3) AS weeks, SUM(sw_sowing.quantity) AS plant_sowing,
                           SUM(IF(ROUND(DATEDIFF(TIMESTAMPADD(DAY,(6-WEEKDAY(:dates)), :dates), sw_sowing.date)/7)>=sw_sowing.weeks_prod, sw_sowing.quantity,0)) AS plant_production,
                           ((SUM(sw_sowing.quantity))/pr_products.plant_m2) AS area_planting
                    FROM (
                          SELECT MAX(id) AS id
                          FROM sw_sowing
                          WHERE status != 0
                          AND id_tenant = :id_tenant
                          AND date <= :dates
                          AND multiply != 1
                          AND id_product = 1
                          GROUP BY id_production_unit_detail
                    ) AS sw
                    INNER JOIN sw_sowing ON sw_sowing.id = sw.id
                    INNER JOIN pr_products ON pr_products.id = sw_sowing.id_product
                    INNER JOIN pr_varieties ON pr_varieties.id = sw_sowing.id_variety
                    WHERE pr_varieties.code != 1
                    GROUP BY sw_sowing.id_product, sw_sowing.type
                    HAVING type NOT IN('ER','PR')
              ) AS s";

$statement    = $this->db->prepare($sql);

//get the sunday dates between two dates and bind the variables
for ($i = $dateInitial; $i <= $dateFinal ; $i = strtotime('+1 day', $i)) {
        if (date('N', $i) == 7){
          $values = [
            ':dates'      => date("Y-m-d", $i),
            ':id_tenant'  => 1
          ];

          $types = [
            ':dates'      => Column::BIND_PARAM_STR,
            ':id_tenant'  => Column::BIND_PARAM_INT
          ];

          $result   = $this->db->executePrepared($statement, $values, $types);
          $final[]  = $result->fetchAll(Phalcon\Db::FETCH_ASSOC);
        }
      }
      return $final;
但尽管如此,它并没有那么快。查询持续5秒,我希望它更快

我还为这些表编制了索引。我想就如何最好地优化这个查询,或者如果我做查询的方式不够,提出一些意见

这是我以前问过的一个问题,关于我为什么使用GROUPBY和MAXid


优化的最简单方法是创建一个过程,该过程:

将开始日期和结束日期作为参数 循环浏览日期以查找星期天,并将其放入临时表中 使用temp表连接查询并一次返回所有查询 通过这种方式,您可以执行实际查询一次,而不是52次。应该快得多

需要检查的另一件事是内部查询的GROUPBY子句。查询只返回MAXid,因此不需要GROUPBY

临时表的示例用法:

create procedure sp_sample( in_start date, in_end date)
begin

declare v_date date;

SELECT in_start + INTERVAL 6 - weekday(in_start) day into v_date;

drop temporary table if exists sundays_tmp;
create temporary table sundays_tmp (
d date
);

while (v_date<in_end) do
  insert into sundays_tmp values (v_date);

  select v_date + INTERVAL 7 day into v_date;
end while;

-- Your query here

end

优化的最简单方法是创建一个过程,该过程:

将开始日期和结束日期作为参数 循环浏览日期以查找星期天,并将其放入临时表中 使用temp表连接查询并一次返回所有查询 通过这种方式,您可以执行实际查询一次,而不是52次。应该快得多

需要检查的另一件事是内部查询的GROUPBY子句。查询只返回MAXid,因此不需要GROUPBY

临时表的示例用法:

create procedure sp_sample( in_start date, in_end date)
begin

declare v_date date;

SELECT in_start + INTERVAL 6 - weekday(in_start) day into v_date;

drop temporary table if exists sundays_tmp;
create temporary table sundays_tmp (
d date
);

while (v_date<in_end) do
  insert into sundays_tmp values (v_date);

  select v_date + INTERVAL 7 day into v_date;
end while;

-- Your query here

end
将给你一个星期号码,你可以用它来分组。使用它可以让您在一次过程中获得所有结果,而不需要一个包含SELECT的应用程序循环

我不理解MAXid的意义,所以我无法解决其余的问题

将给你一个星期号码,你可以用它来分组。使用它可以让您在一次过程中获得所有结果,而不需要一个包含SELECT的应用程序循环


我不理解MAXid的意义,所以我无法解决其余的问题。

您是否考虑过在单个查询中使用最小和最大日期?然后,您可以按日期分组,只需一个查询即可。循环越长,此查询运行多次将越慢。n+1@MHewison是的,我理解,但在这种情况下,我需要这样做,因此,我必须在日期之间为星期天做一个循环,这对于数据库来说并不是一项真正的任务。为了使php方面更好,你还可以从开始日开始找到第一个星期天,然后再找到+7天。在更大的范围内,它可能会更快。您是否考虑过在单个查询中使用最小和最大日期?然后,您可以按日期分组,只需一个查询即可。循环越长,此查询运行多次将越慢。n+1@MHewison是的,我理解,但在这种情况下,我需要这样做,因此,我必须在日期之间为星期天做一个循环,这对于数据库来说并不是一项真正的任务。为了使php方面更好,你还可以从开始日开始找到第一个星期天,然后再找到+7天。在更大的范围内它可能会更快。谢谢你,但你能给我一个临时表的例子吗?这是一个例子,为什么我必须使用MAXid和groupby,你有超过id的groupby生产单位详细信息,这意味着你将获得每个id生产单位详细信息的MAXid。但是,主查询没有id\u生产\u单位\u详细信息的引用,因此很难理解为什么这是正确的。谢谢你,但是你能给我一个临时表的例子吗?这是一个例子,为什么我必须使用MAXid和groupby,你有超过id的groupby生产单位详细信息,这意味着你将获得每个id生产单位详细信息的MAXid。但是,主查询没有对id\u production\u unit\u详细信息的引用,因此很难理解为什么这是正确的。谢谢你的回答,我需要MAXid,因为这谢谢你的回答,我需要MAXid,因为这