[英]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
假設id
在property
表中是唯一的。 這應該能夠有效地使用具有前導列deal_finish
, status
和is_confirm
的索引,以消除考慮的某些行。
... ON property (deal_finish,status,is_confirm,...)
設置好之后,我們可以在外部查詢中將其作為內聯視圖(派生表)引用,並且外部查詢可以將其聯接到其他表。
請注意,如果我們在product_images
和product_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.