如何在另一次选择中多次重复选择时进行优化?
问题描述:
我正在计算一个大型数据库中两个日期之间的营业时间,它正在工作。 但是这个请求很长,因为有很多选择。 我想优化它,但似乎我不能使用别名。 任何想法?如何在另一次选择中多次重复选择时进行优化?
这里是我的问题的看法:
我有一个第一次约会:选择A:
SELECT CASE
WHEN (... = 9)
THEN (SELECT ...)
ELSE (SELECT ... FROM ...
WHERE ((...) AND (...) AND
((...='1' OR ...'10009' OR ...='10011') AND ...='3'))
)
END
FROM ...
和我的第二个日期:SELECT B:
SELECT
CASE
WHEN (...) AND ...
THEN( SELECT ... FROM ...
WHERE ((...
AND (...) AND (...)
AND (...)) )
WHEN (...) AND ...
THEN( SELECT ... FROM ...
WHERE (...) AND ... AND ... AND ... AND ...)
ELSE NULL
END
)
然后我将它们复制在下面的查询中(这是在另一个大查询中......对于具有多列的报告):
SELECT (TIMESTAMPDIFF(MINUTE, GetBusinessHours(SELECT A),GetBusinessHours(SELECT B))
- 13*60*DATEDIFF(GetBusinessHours(SELECT B) , GetBusinessHours(SELECT A))
- 2*11*60*(WEEK(SELECT B) - WEEK(SELECT A))
- SELECT COUNT(*) FROM X WHERE DATE BETWEEN ((SELECT A) AND (SELECT B))
因此,这最后一个查询变得巨大,它需要70行。有没有一种方法来优化事实,我不必重新计算每个SELECT A和SELECT B 4次?
答
计划A:使用公共数据创建临时表。
计划B:使用@variables。例如:
SELECT @A := expression1...;
SELECT @B := expression2...;
SELECT ... @A ... @B ... @A ...
使用'explain'来准确指出它的速度慢。不要一直计算结果,缓存它(或实现它)。剩下的事情就是创建一个事件,根据间隔时间为你预先计算这个事件,这样你的应用程序就可以读取数据了(它总是很快)。在解释输出到达之前,我们可以推测什么确实很慢。由于这是一个很大的数据库,我怀疑还有一些繁重的磁盘寻找,我们通过为此目的分配RAM来避免。 – Mjh
谢谢。 我检查了解释并看到100000+行10次。它位于我的SELECT A或B之一的依赖子查询中,但这些行与其他行不同。 类型是索引,possible_keys是空的,ref是空的并且在Extra:using索引中说。 我会检查它的确切位置,并尝试从所有脚本中提取。 –
好吧,它正在进行全表扫描。发布表结构,解释和精确查询的确切输出将有所帮助,但似乎您正在使用表的全部内容来计算营业时间。这涉及到磁盘寻道,因为你可能有一个机械驱动器(而不是SSD) - 需要一段时间才能找到数据。我怀疑你可以轻松地进行优化,而无需缓存结果并在将来的查询中使用缓存。 – Mjh