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