簡體   English   中英

在mysql中使用多個聯接時加快查詢速度

[英]Speed up the query when using multiple joins in mysql

我在需要連接5個表的地方有sql查詢。 到目前為止,我已經嘗試過此查詢。 它正在工作,但需要很長時間。 在這里可以做些什么來優化以下查詢?

$select_query = 'select ';

        $select_query .= "ROUND((
                             6371 * ACOS(
                               COS(RADIANS('.$lat.'))  COS(RADIANS(lat))  COS(
                                 RADIANS(lng) - RADIANS('.$lng.')
                               ) + SIN(RADIANS('.$lat.')) * SIN(RADIANS(lat))
                             )
                           ),2) AS property_distance ,";

        $select_query .= "
                        pro.id as id,
                        pro.user_id,
                        pro.category_id,
                        pro.total_price,
                        pro.size,
                        pro.lat,
                        pro.lng,
                        pro.city,
                        pro.city_english,
                        pro.created_at,
                        pimg.image as property_images,
                        pimg.property_id,
                        pa.property_id,
                        pa.category_attribute_id,
                        pa.is_multiple_data,
                        pa.attribute_value,

                        ca.category_id,
                        ca.attribute_name,
                        ct.category_id,
                        ct.category_name,

                        cat.attribute_id,
                        cat.attribute_label,
                        cat.locale

                     FROM
                        property pro FORCE INDEX (property_index)
                    left join property_images pimg on pro.id=pimg.property_id

                    JOIN property_attributes pa ON
                        pa.property_id = pro.id

                    left JOIN category_attributes ca ON
                        ca.id = pa.category_attribute_id

                    left JOIN category_attributes_translations cat ON
                        ca.id = cat.attribute_id

                    left JOIN categories_translation ct ON
                        pro.category_id = ct.category_id

                    WHERE pro.is_confirm='1' and pro.status='1' and pro.deal_finish='0' and cat.locale='" . $locale . "' and ct.locale='" . $locale . "'

                    GROUP BY pro.id HAVING property_distance<=10 ORDER by pro.id DESC";

然后最終運行此查詢。

請為我建議優化此查詢的正確方法。

在進行任何聯接之前,我將修改查詢以遍歷屬性表並消除盡可能多的行。 HAVING子句中有關大圓距離計算結果的條件將要求該計算必須在WHERE子句沒有消除的每一行上進行。

我只針對property表編寫查詢,如下所示:

         SELECT ROUND( ( 6371 * ACOS( COS(RADIANS( :lat ) ) 
                                    * COS(RADIANS(pro.lat))
                                    * COS(RADIANS(pro.lng) - RADIANS( :lng ) ) 
                                    + SIN(RADIANS( :lat ))
                                    * SIN(RADIANS(pro.lat))
                                )
                       )
                ,2) AS property_distance
              , pro.id
              , pro.user_id
              , pro.category_id
              , pro.total_price
              , pro.size
              , pro.lat
              , pro.lng
              , pro.city
              , pro.city_english
              , pro.created_at
           FROM property pro
          WHERE pro.is_confirm  = '1' 
            AND pro.status      = '1'
            AND pro.deal_finish = '0'
         HAVING property_distance <= 10
          ORDER
             BY pro.id DESC

假設idproperty表中是唯一的。 這應該能夠有效地使用具有前導列deal_finishstatusis_confirm的索引,以消除考慮的某些行。

   ... ON property (deal_finish,status,is_confirm,...)

設置好之后,我們可以在外部查詢中將其作為內聯視圖(派生表)引用,並且外部查詢可以將其聯接到其他表。

請注意,如果我們在product_imagesproduct_attributes有多個匹配的行,則對兩個表進行聯接將創建一個半笛卡爾乘積, product_image每一行與product_attribute每一行都匹配。 即,從20行product_image交叉連接到從20行product_attribute將產生一組400個的行。

SELECT c.*
  FROM (  -- inline view query
          SELECT ROUND( ( 6371 * ACOS( COS(RADIANS( :lat ) ) 
                                    * COS(RADIANS(pro.lat))
                                    * COS(RADIANS(pro.lng) - RADIANS( :lng ) ) 
                                    + SIN(RADIANS( :lat ))
                                    * SIN(RADIANS(pro.lat))
                                )
                       )
                ,2) AS property_distance
              , pro.id
              , pro.user_id
              , pro.category_id
              , pro.total_price
              , pro.size
              , pro.lat
              , pro.lng
              , pro.city
              , pro.city_english
              , pro.created_at
           FROM property pro
          WHERE pro.is_confirm  = '1' 
            AND pro.status      = '1'
            AND pro.deal_finish = '0'
         HAVING property_distance <= 10
          ORDER BY pro.id DESC
       ) c

  LEFT
  JOIN product_images pimg 
    ON pimg.product_id = c.id

 ORDER BY c.id DESC

現在,出現了使用GROUP BY折疊行的整個問題,並且表達式在功能上不依賴於ONLY_FULL_GROUP_BY sql_mode等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM