我正在运行一个超过5分钟的查询以产生结果。当我将LEFT JOIN中的DATE(NOW)更改为一列时需要9秒。以下是显示更快线的查询
SELECT DISTINCT(rental.id), filmCopy.location fC_id, member.id m_id, filmInfo.title fI_title, member.name, member.surname, member.cellphone, member.telephone, rental.due_back,rental.returned, filmCopy.on_loan_to, filmInfo.folder fI_folder, reservation_date rsrvtn, reservation.id res_id
FROM rental
INNER JOIN transactionSummary ON transactionSummary.id = rental.transactionSummary_id
INNER JOIN member ON member.id = transactionSummary.member_id
INNER JOIN filmCopy ON filmCopy.id = rental.filmCopy_id
INNER JOIN filmInfo ON filmInfo.id = filmCopy.filmInfo_id
INNER JOIN filmPriceBracket ON filmPriceBracket.filmInfo_id = filmInfo.id
AND filmPriceBracket.filmCopytype_id = filmCopy.filmCopyType_id
LEFT JOIN reservation ON reservation.filmInfo_id = filmInfo.id
快得多 - LEFT JOIN预约ON reservation.filmInfo_id = filmInfo.id AND reservation.reservation_date = DATE(rental.due_back)
AND reservation.reservation_date = DATE(NOW())
WHERE rental.due_back < DATE_SUB(NOW(), INTERVAL 1 DAY)
AND rental.returned IS NULL
AND filmPriceBracket.filmCopyType_id !=24
AND filmPriceBracket.filmCopyType_id !=23
ORDER BY fI_folder, rsrvtn DESC, filmCopy_id, rental.due_back
慢速查询给了我正确的结果,因为快速的一个是好的但不完整。 关于为什么使用今天DATE的任何建议都会让它变得如此缓慢?
对于背景信息,它会提取过期电影的报告以及保留(过期和未过期) 感谢
修改
这是我从下面的答案中得到的结果,但是语法中出现错误..
DECLARE @NOW DATE
SELECT @NOW := DATE(NOW())
SELECT DISTINCT(rental.id), filmCopy.location fC_id, member.id m_id, filmInfo.title fI_title, member.name, member.surname, member.cellphone, member.telephone, rental.due_back,rental.returned, filmCopy.on_loan_to, filmInfo.folder fI_folder, reservation_date rsrvtn, reservation.id res_id
FROM rental
INNER JOIN transactionSummary ON transactionSummary.id = rental.transactionSummary_id
INNER JOIN member ON member.id = transactionSummary.member_id
INNER JOIN filmCopy ON filmCopy.id = rental.filmCopy_id
INNER JOIN filmInfo ON filmInfo.id = filmCopy.filmInfo_id
INNER JOIN filmPriceBracket ON filmPriceBracket.filmInfo_id = filmInfo.id
AND filmPriceBracket.filmCopytype_id = filmCopy.filmCopyType_id
LEFT JOIN reservation ON reservation.filmInfo_id = filmInfo.id
AND reservation.reservation_date = @NOW
WHERE $where
AND rental.returned IS NULL
AND filmPriceBracket.filmCopyType_id !=24
AND filmPriceBracket.filmCopyType_id !=23
ORDER BY fI_folder, rsrvtn DESC, filmCopy_id, rental.due_back
答案 0 :(得分:2)
您可以尝试首先创建包含DATE(NOW())
和DATE_SUB(...)
值的两个变量,这样就不必为每条记录评估它们。
这样的事情应该在MySQL中做到:
DECLARE @NOW DATE;
DECLARE @YESTERDAY DATE;
SELECT @NOW := DATE(NOW());
SELECT @YESTERDAY := DATE_SUB(@NOW, INTERVAL 1 DAY);
...
AND reservation.reservation_date = @NOW
WHERE rental.due_back < @YESTERDAY
...
答案 1 :(得分:0)
首先验证两个查询确实返回相同数量的行(我曾经多次咬过这个行)。
然后,您可以通过执行来避免对每行进行DATE(NOW())
评估 - 这是MySQL语法;你没有说你正在使用什么数据库 -
SELECT @DATENOW:=DATE(NOW());
SELECT @DATESUB:=DATE_SUB(NOW(), INTERVAL 1 DAY)
并使用@DATENOW
和@DATESUB
代替DATE(NOW())
和DATE_SUB(NOW(), INTERVAL 1 DAY)
。
通常,您希望所有生成常量或几乎常量的表达式(在查询期间NOW()实际变化)显式为常量。如果您可以以编程方式构建查询,也可以执行此应用程序端:
# very pseudo code
query := 'SELECT ... ' + date_format(...) + '...'
run_query( query )
答案 2 :(得分:0)
通过编写reservation.reservation_date = DATE(NOW())
,您为每个满足在where子句上定义的过滤器的记录调用NOW()函数,这是您的SQL代码的瓶颈。
你可以为DATE(NOW())条件定义一个变量并改为使用它。
注意:如果您使用的是oracle系统,可以使用 with 子句传递变量