mysql在使用大于/小于条件的嵌套查询以及对大型表的限制时未完成执行
我已经玩了好几天这个问题mysql在使用大于/小于条件的嵌套查询以及对大型表的限制时未完成执行,mysql,sql,Mysql,Sql,我已经玩了好几天这个问题 select slno,Power_Factor_L32_Avg from power_logger pl where (pl.slno between 1851219 and 2042099) and meter_id="logger1" and pl.Power_Factor_L32_Avg is not null and case when (((pl.slno=1851219) and ((pl.Power_
select slno,Power_Factor_L32_Avg
from power_logger pl
where (pl.slno between 1851219 and 2042099)
and meter_id="logger1"
and pl.Power_Factor_L32_Avg is not null
and case when (((pl.slno=1851219)
and ((pl.Power_Factor_L32_Avg) not between 0.400 and 1.000))
or ((pl.slno=2042099) and
((pl.Power_Factor_L32_Avg) not between 0.400 and 1.000))
or ((pl.Power_Factor_L32_Avg not between 0.400 and 1.000) and
(((select p2.Power_Factor_L32_Avg
from power_logger p2
where p2.slno=(select slno
from power_logger
where slno>pl.slno
and Power_Factor_L32_Avg is not null
order by slno asc limit 1))
between 0.400 and 1.000)
or ((select p4.Power_Factor_L32_Avg
from power_logger p4
where p4.slno=(select slno
from power_logger
where slno<pl.slno
and Power_Factor_L32_Avg is not null
order by slno desc limit 1 ))
between 0.400 and 1.000))))
then (case when (((pl.slno=1851219)
and ((select p10.Power_Factor_L32_Avg
from power_logger p10
where p10.slno=pl.slno+1) is null
or (select p10.Power_Factor_L32_Avg
from power_logger p10
where p10.slno=pl.slno+1) between 0.400 and 1.000))
or (((select p5.Power_Factor_L32_Avg
from power_logger p5
where p5.slno=(select slno
from power_logger
where slno<pl.slno
and Power_Factor_L32_Avg is not null
order by slno desc limit 1 ))
between 0.400 and 1.000)
and ((select p6.Power_Factor_L32_Avg
from power_logger p6
where p6.slno=(select slno
from power_logger
where slno>pl.slno
and Power_Factor_L32_Avg is not null
order by slno asc limit 1 ))
between 0.400 and 1.000)))
then 0=1
else 1
end)
else 0=1
end
order by slno asc
这是为了测试功率因数为null的下一个slno是否与功率记录器表中的slno一起提取。这也行不通。我不确定是否还有其他方法可以在不使用大于符号的情况下获得下一个slno。我的意见是,您在案例陈述方面做的工作太多了。你也在重复很多工作 首先,为p1中的每一行预计算此结果,并将其存储在临时表中:
select slno
from power_logger
where slno<pl.slno
and Power_Factor_L32_Avg is not null
order by slno desc limit 1
这将有助于降低时间,尤其是使用临时表。如果没有,请将新版本重新发布,我们可以尝试用“JOIN”替换部分子查询,这将再次提高效率。通过修改Hbcdev的答案 从中选择c.slno、c.Power\u Factor\u L32\u Avg 选择p.slno作为cur,a.slno作为next,@s1作为prev,@s1:=p.slno from 选择@s1:=0 d,power\u logger p join选择a.slno,@s作为prev,@s:=a.slno ne from 电源记录器a,选择@s:=0 c,其中a.slno介于1851219和2042099之间 a.Power_Factor_L32_Avg不为空,a.meter_id='logger1'作为a.prev=p.slno上的a.meter_id='logger1' 其中,1851219和2042099之间的p.slno和p.Power_Factor_L32_Avg不为空,且 p、 仪表id='logger1'd,功率记录器c,其中c.slno=d.cur和c.slno=1851219或c.slno=2042099,c.power\u Factor\u L32\u Avg不在0.400和1.000之间 或c.功率因数平均值 不在0.400和1.000之间,从功率记录器p2中选择p2.Power\u Factor\u L32\u Avg 其中p2.slno=d。下一步介于0.4和1.000之间,或选择p3.Power\u Factor\u L32\u Avg 来自功率记录器p3,其中p3.slno=d.prev介于0.4和1.000之间 而不是c.slno=1851219,从功率记录器p10中选择p10.Power\u Factor\u L32\u Avg 其中p10.slno=c.slno+1为空或从功率记录器p10中选择p10.Power\u Factor\u L32\u Avg 其中p10.slno=c.slno+1介于0.400和1.000之间,或选择p5.Power\u Factor\u L32\u Avg 来自功率记录器p5,其中p5.slno=d.prev介于0.400和1.000之间,并且 从功率记录器p6中选择p6.Power\u Factor\u L32\u Avg,其中p6.slno=d slno asc的订单在0.400到1.000之间
这将在大约6秒钟内执行。尝试更改这些选项以选择TOP 1,而不是在末尾设置LIMIT 1。也许MySQL可以更好地优化这些子查询,这样您就不会看到如此大的减速。@Hbcdev:谢谢您的快速响应。使用TOP 1时出现语法错误。我以前没有使用过它,我想它只适用于transact-sql。这不是一个查询。这是一个电子表格宏。非常感谢您的回复。不幸的是,通过将case语句更改为布尔逻辑,它只返回两行,并且需要更多的执行时间。另外,如果我们使用临时表,我们仍然必须使用select语句从临时表中选择slno,我认为这和当前查询的效果一样好。使用嵌套的select语句会把整个事情搞糟。它与所有case语句一起完美执行,并将嵌套的select查询替换为slno=pl.slno+1/slno=pl.slno-1。我确实必须使用嵌套选择,因为我需要下一个slno,其中功率因数\u L32\u平均值不为null,pl.slno+1或pl.slno-1处的功率因数\u L32\u平均值可能为null。请使用临时表。这将比你已经拥有的要快得多。临时表将保留在内存中,停止查询重复工作,并将涉及一个更简单的查询来查找正确的行。试试看!我尝试使用临时表,但问题是在单个select语句中不能多次引用临时表,并且出现错误无法重新打开临时表。请将其与join合并。将临时表与实际表联接,然后在临时表的另一列上再次联接原始表。然后,您将可以访问原始表和查询中任何地方的前一个slno行。它会快得多,快得多。
select slno
from power_logger
where slno<pl.slno
and Power_Factor_L32_Avg is not null
order by slno desc limit 1
create temporary table temp(
slno int
,other_slno int
);
INSERT INTO temp(slno, other_slno)(
SELECT main.slno, second.slno
FROM power_logger main
JOIN (SELECT other.slno FROM power_logger AS other
where other.slno< main.slno
and Power_Factor_L32_Avg is not null
order by other.slno desc limit 1) second
);
(select p4.Power_Factor_L32_Avg
from power_logger p4
where p4.slno=(select slno
from power_logger
where slno<pl.slno
and Power_Factor_L32_Avg is not null
order by slno desc limit 1 )
WHERE <Other clauses> ....
AND (
((pl.slno=1851219)
and ((pl.Power_Factor_L32_Avg) not between 0.400 and 1.000))
or ((pl.slno=2042099) and
((pl.Power_Factor_L32_Avg) not between 0.400 and 1.000))
or ((pl.Power_Factor_L32_Avg not between 0.400 and 1.000) and
(((select p2.Power_Factor_L32_Avg
from power_logger p2
where p2.slno=(select slno
from power_logger
where slno>pl.slno
and Power_Factor_L32_Avg is not null
order by slno asc limit 1))
between 0.400 and 1.000)
or ((select p4.Power_Factor_L32_Avg
from power_logger p4
where p4.slno=(select slno
from power_logger
where slno<pl.slno
and Power_Factor_L32_Avg is not null
order by slno desc limit 1 ))
between 0.400 and 1.000)))
AND NOT
((pl.slno=1851219)
and ((select p10.Power_Factor_L32_Avg
from power_logger p10
where p10.slno=pl.slno+1) is null
or (select p10.Power_Factor_L32_Avg
from power_logger p10
where p10.slno=pl.slno+1) between 0.400 and 1.000))
or (((select p5.Power_Factor_L32_Avg
from power_logger p5
where p5.slno=(select slno
from power_logger
where slno<pl.slno
and Power_Factor_L32_Avg is not null
order by slno desc limit 1 ))
between 0.400 and 1.000)
and ((select p6.Power_Factor_L32_Avg
from power_logger p6
where p6.slno=(select slno
from power_logger
where slno>pl.slno
and Power_Factor_L32_Avg is not null
order by slno asc limit 1 ))
between 0.400 and 1.000))
)