我写了一个查询,但是要花很多时间。我想知道是否存在无需在MYSQL中创建临时表即可对其进行优化的解决方案。由于AccessLog2019庞大,因此有一种方法可以优化子查询部分,因此需要花费很多时间)
这是我的查询
SELECT distinct l.ListingID,l.City,l.ListingStatus,l.Price,l.Bedrooms,l.FullBathrooms, gc.Latitude,gc.Longitude , count(distinct s.AccessLogID) AS access_count, s.LBID , lb.CurrentListingID
from lockbox.Listings l
JOIN lockbox.GeoCoordinates gc ON l.ListingID = gc.ID
LEFT JOIN lockbox.LockBox lb ON l.ListingID = lb.CurrentListingID
LEFT JOIN
(SELECT * FROM lockbox.AccessLog2019 ac where ac.AccessType not in('1DayCodeGen','BluCodeGen','SmartMACGen') AND DATEDIFF(NOW(), ac.UTCAccessedDT ) < 1 ) s
ON lb.LBID = s.LBID
WHERE l.AssocID = 'AS00000000CC' AND (gc.Confidence <> '5 - Unmatchable' OR gc.Confidence IS NULL OR gc.Confidence = ' ')
group BY l.ListingID
谢谢
答案 0 :(得分:2)
如果您可以避免使用外部group by
,那将是一个很大的胜利。我在想:
SELECT l.ListingID, l.City, l.ListingStatus, l.Price, l.Bedrooms, l.FullBathrooms,
gc.Latitude, gc.Longitude,
(select count(*)
from lockbox.LockBox lb join
lockbox.AccessLog2019 ac
on lb.LBID = ac.LBID
where l.ListingID = lb.CurrentListingID and
ac.AccessType not in ('1DayCodeGen', 'BluCodeGen', 'SmartMACGen') and
DATEDIFF(NOW(), ac.UTCAccessedDT) < 1
) as cnt
from lockbox.Listings l JOIN
lockbox.GeoCoordinates gc
ON l.ListingID = gc.ID
WHERE l.AssocID = 'AS00000000CC' AND
(gc.Confidence <> '5 - Unmatchable' OR
gc.Confidence IS NULL OR
gc.Confidence = ' '
)
注意:这不会选择s.LBID
或lb.CurrentListingID
,因为它们在您的查询中没有意义。如果我理解正确,那么它们在不同的行上可能具有不同的值。
答案 1 :(得分:1)
您可以尝试将子查询分解为JOIN子句。
它可能会向优化程序提示它可以先使用LBID字段,然后再测试AccessType(以防优化程序在选择子选项时不知道这一点)。
SELECT distinct l.ListingID,l.City,l.ListingStatus,l.Price,l.Bedrooms,l.FullBathrooms, gc.Latitude,gc.Longitude , count(distinct s.AccessLogID) AS access_count, s.LBID , lb.CurrentListingID
from lockbox.Listings l
JOIN lockbox.GeoCoordinates gc ON l.ListingID = gc.ID
LEFT JOIN lockbox.LockBox lb ON l.ListingID = lb.CurrentListingID
LEFT JOIN AccessLog2019 s
ON lb.LBID = s.LBID
AND s.AccessType not in('1DayCodeGen','BluCodeGen','SmartMACGen')
AND DATEDIFF(NOW(), s.UTCAccessedDT ) < 1
WHERE l.AssocID = 'AS00000000CC' AND (gc.Confidence <> '5 - Unmatchable' OR gc.Confidence IS NULL OR gc.Confidence = ' ')
group BY l.ListingID
请注意,这是JOIN子句中的条件给出与使用WHERE子句不同的行为的情况之一。如果您只有lb.LBID = s.LBID
,然后又有我在外部查询的WHERE
中编写的条件,则结果将有所不同。他们将排除与lb.LBID = s.LBID
匹配的记录。但是在JOIN
子句中,它是外部联接条件的一部分。
答案 2 :(得分:1)
SELECT *
->仅选择所需的列。SELECT DISTINCT ... GROUP BY
-只能做一个或一个,不要两个都做。INDEX(AssocID, ListingID)
(按此顺序)DATEDIFF(NOW(), ac.UTCAccessedDT ) < 1
-> ac.UTCAccessedDT > NOW() - INTERVAL 1 DAY
(或您的意图是什么。然后添加INDEX(UTCAccessedDT)
OR
难以优化;考虑清理数据,以使Confidence
的3个值相同。