我刚才写了这个查询,似乎工作正常。
但是最近当这个查询运行时,它通常不会返回任何结果。 Ajax调用永远不会收到响应。如果我在phpMyAdmin中运行它是一样的,通常它可以工作,但有时它只是挂起。
就像那几个小时,然后它又开始恢复正常了。
我不确定我的查询是否存在导致服务器阻塞的问题,或者服务器本身是否存在问题。
这是运行的查询。我没有sql pro,所以也许有人注意到它有一个大问题,我应该采取不同的处理方式?如果我运行它,并且我收到响应,通常需要1.5 / 2秒才能完成。
SELECT country.CountryID,
accommodation.AccommodationID,
accommodation.CityID,
accommodation.lodgement,
accommodation.SumID,
accommodation.RegionID,
accommodation.starrating,
accommodation.reviewrating,
images.image1 AS image,
summary.name,
summary.lowestprice,
summary.lowestpricedate,
summary.url
FROM country
INNER JOIN accommodation ON accommodation.CountryID = country.CountryID
INNER JOIN images ON images.AccommodationID = accommodation.AccommodationID
INNER JOIN cities ON cities.CityID = accommodation.CityID
INNER JOIN summary ON summary.SumID = accommodation.SumID
WHERE country.name = 'x'
ORDER BY accommodation.reviewrating DESC LIMIT 0,25
答案 0 :(得分:0)
您是否在连接中使用的所有列上都有索引?
country.CountryID
,accommodation.AccommodationID
,cities.CityID
和summary.SumID
都需要是主键。
accommodation.CountryID
,images.AccommodationID
,accommodation.CityID
,accommodation.SumID
和country.name
都需要索引。
答案 1 :(得分:0)
您的问题可以在这一行
ORDER BY accommodation.reviewrating DESC LIMIT 0,25
虽然使用LIMIT MySQL必须在选择第一个之前通过审核对所有住宿行进行排序。尝试使用以下方法创建新索引:
CREATE INDEX ON accommodation (CountryID, reviewrating);
因为您可能会注意到查询需要在桌子上进行全面扫描。
答案 2 :(得分:0)
如果没有关于表格中的架构和行数的大量详细信息,很难确切知道查询性能的恶化原因。但我怀疑这是因为你的桌子越来越大了。祝贺一个成功的应用程序,并欢迎关注您的RDMS,以确保它继续正确扩展。
延迟加入技术可能会非常有用。这是这样的。
首先,找出您需要报告的AccommodationID
值。在您正在使用的查询中,可以这样做:
SELECT AccomodationID
FROM accomodation
JOIN country USING(CountryID)
WHERE country.name = 'x'
ORDER BY reviewrating DESC
LIMIT 0,25
如果你在(CountryID, reviewrating)
上制作一个复合索引,这将非常快。 (如果您正在使用MyISAM表,请在(CountryID, reviewrating, AccomodationID)
上创建一个复合索引。)它将提取前25个评论的ID。
接下来,在主查询中使用子查询 - 25个项目的列表。
SELECT country.CountryID,
accommodation.AccommodationID,
accommodation.CityID,
accommodation.lodgement,
accommodation.SumID,
accommodation.RegionID,
accommodation.starrating,
accommodation.reviewrating,
images.image1 AS image,
summary.name,
summary.lowestprice,
summary.lowestpricedate,
summary.url
FROM country
INNER JOIN accommodation ON accommodation.CountryID = country.CountryID
INNER JOIN images ON images.AccommodationID = accommodation.AccommodationID
INNER JOIN cities ON cities.CityID = accommodation.CityID
INNER JOIN summary ON summary.SumID = accommodation.SumID
INNER JOIN (
SELECT AccomodationID
FROM accomodation
JOIN country USING(CountryID)
WHERE country.name = 'x'
ORDER BY reviewrating DESC
LIMIT 0,25
) ids ON accomodation.AccomodationId = ids.AccomodationId
ORDER BY accommodation.reviewrating DESC LIMIT 0,25
为什么这有效?它不会创建一个大的结果集,并且它只会丢弃除25行以外的所有结果集。相反,它使用已经排序的索引非常精确地收集它所需的ID,然后创建一个小得多的最终结果集。
这称为延迟连接,因为它会推迟大连接操作,直到选择了正确的行子集为止。