基于每个日期使用php进行酒店搜索的数据库的结果更快

时间:2013-07-27 09:36:58

标签: mysql sql

我正在开发一个酒店搜索引擎。对于每个日期,它都有hotel infohotel 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

1 个答案:

答案 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声明正在扼杀你。

此外,在性能方面,我先看看两件事:

  1. 查询计划缓存
  2. 索引
  3. 查询计划缓存

    很多人会为此争论,但我个人见过。通常最好采用这种大小的查询,并将其转换为存储过程。为什么?因为查询计划是缓存的。请记住,服务器花费了大量精力来确定如何来运行查询。

    最近,数据库引擎在缓存计划方面变得更加智能。例如,如果要参数化查询,而不是在WHERE子句中发送原始值(哦,我不打算提及SQL注入),它可以在第一次运行后缓存该查询计划。

    索引

    索引将成为关键,最有可能。最重要的是,虽然我爱我一个覆盖索引,但你想确保它不是扫描表。因此,举例来说,您需要确保city上的索引以及sdate上的索引。这将允许引擎利用有序索引来至少过滤查询。

    覆盖索引,这是你真正开始看到性能提升的地方,这在这里是不现实的,因为你正在拉回这么多领域。如果您偶然不需要所有这些字段,那么请将其修剪下来,并且您也可以利用覆盖的索引。