我正在开发一个酒店搜索引擎。对于每个日期,它都有hotel info
,hotel availability
等表格。它工作正常,但与其他酒店搜索引擎(如easytobook或hotel.com)相比,结果很慢。我的问题是:我怎样才能让它更快?目前它使用PHP直接从数据库中获取结果。
这是用于从数据库中提取结果的当前查询
SELECT DISTINCT t_hotel_info.hotelid,
t_hotel_info.hotelname,
t_hotel_info.description,
t_hotel_info.userid,
t_hotel_info.starrating,
t_hotel_info.currency,
t_hotel_info.hotel_url,
t_hotel_info.address1,
t_hotel_info.state,
t_hotel_info.country,
t_hotel_images1.imagepath1
FROM t_hotel_info
INNER JOIN t_hotel_images1
ON t_hotel_info.userid = t_hotel_images1.userid
INNER JOIN t_hotel_availability
ON t_hotel_info.userid = t_hotel_availability.userid
INNER JOIN t_hotel_account_info
ON t_hotel_info.userid = t_hotel_account_info.userid
INNER JOIN t_hotel_facilities
ON t_hotel_info.userid = t_hotel_facilities.userid
WHERE city = '$_GET[city]'
AND t_hotel_availability.sdate >= '$_GET[checkin]'
AND t_hotel_availability.sdate < '$_GET[checkout]'
AND t_hotel_availability.roomrate <> 0
这是我对表格的解释说明
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t_hotel_facilities ALL NULL NULL NULL NULL 627 Using temporary
1 SIMPLE t_hotel_info ref PRIMARY PRIMARY 4 ezee2book.t_hotel_facilities.UserID 8 Using where
1 SIMPLE t_hotel_account_info ALL NULL NULL NULL NULL 767 Using where; Using join buffer
1 SIMPLE t_hotel_images1 ALL NULL NULL NULL NULL 732 Using where; Using join buffer
1 SIMPLE t_hotel_availability ALL NULL NULL NULL NULL 51806 Using where; Distinct; Using join buffer
答案 0 :(得分:1)
首先,我很确定你可以修剪一下:
SELECT DISTINCT t_hotel_info.hotelid,
t_hotel_info.hotelname,
t_hotel_info.description,
t_hotel_info.userid,
t_hotel_info.starrating,
t_hotel_info.currency,
t_hotel_info.hotel_url,
t_hotel_info.address1,
t_hotel_info.state,
t_hotel_info.country,
t_hotel_images1.imagepath1
FROM t_hotel_info
INNER JOIN t_hotel_images1
ON t_hotel_info.userid = t_hotel_images1.userid
INNER JOIN t_hotel_availability
ON t_hotel_info.userid = t_hotel_availability.userid
WHERE city = '$_GET[city]'
AND t_hotel_availability.sdate >= '$_GET[checkin]'
AND t_hotel_availability.sdate 0
AND t_hotel_availability.roomrate <> 0
那些额外的JOIN
声明正在扼杀你。
此外,在性能方面,我先看看两件事:
很多人会为此争论,但我个人见过。通常最好采用这种大小的查询,并将其转换为存储过程。为什么?因为查询计划是缓存的。请记住,服务器花费了大量精力来确定如何来运行查询。
最近,数据库引擎在缓存计划方面变得更加智能。例如,如果要参数化查询,而不是在WHERE
子句中发送原始值(哦,我不打算提及SQL注入),它可以在第一次运行后缓存该查询计划。
索引将成为关键,最有可能。最重要的是,虽然我爱我一个覆盖索引,但你想确保它不是扫描表。因此,举例来说,您需要确保city
上的索引以及sdate
上的索引。这将允许引擎利用有序索引来至少过滤查询。
覆盖索引,这是你真正开始看到性能提升的地方,这在这里是不现实的,因为你正在拉回这么多领域。如果您偶然不需要所有这些字段,那么请将其修剪下来,并且您也可以利用覆盖的索引。