1

サブスクリプションの詳細に参加し、距離で並べ替えるメンバーの場所を実行して検索する非常に複雑なクエリがあります。

このロードを高速化するために追加する必要がある正しいインデックスとカーディナリティについて、誰かが指示を与えることができますか。

現在、100 万件のレコードで 75 秒かかりますが、改善できることはわかっています。

ありがとうございました。

SELECT SQL_CALC_FOUND_ROWS (((acos(sin((33.987541*pi()/180)) * sin((users_data.lat*pi()/180))+cos((33.987541*pi()/180)) * cos((users_data.lat*pi()/180)) * cos(((-118.472153- users_data.lon)* pi()/180))))*180/pi())*60*1.1515) as distance,subscription_types.location_limit as location_limit,users_data.user_id,users_data.last_name,users_data.filename,users_data.user_id,users_data.phone_number,users_data.city,users_data.state_code,users_data.zip_code,users_data.country_code,users_data.quote,users_data.subscription_id,users_data.company,users_data.position,users_data.profession_id,users_data.experience,users_data.account_type,users_data.verified,users_data.nationwide,IF(listing_type = 'Company', company, last_name) as name
FROM `users_data`
LEFT JOIN `users_reviews` ON users_data.user_id=users_reviews.user_id AND users_reviews.review_status='2'
LEFT JOIN users_locations ON users_locations.user_id=users_data.user_id
LEFT JOIN subscription_types ON  users_data.subscription_id=subscription_types.subscription_id
WHERE users_data.active='2'
AND subscription_types.searchable='1'
AND users_data.state_code='CA'
AND users_data.country_code='US'
GROUP BY users_data.user_id
HAVING distance <= '50'
OR location_limit='all'
OR users_data.nationwide='1'
ORDER BY subscription_types.search_priority ASC, distance ASC
LIMIT 0,10

説明

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE users_reviews システム user_id,review_status NULL NULL NULL 0 const 行が見つかりません 1 SIMPLE users_locations システム user_id NULL NULL NULL 0 const 行が見つかりません 1 SIMPLE users_data ref subscription_id,active,state_code,country_code state_code 47 const 88241 where を使用します。一時的な使用; filesort の使用 1 SIMPLE subscription_types ALL PRIMARY,searchable NULL NULL NULL 4 where; の使用 結合バッファの使用

4

1 に答える 1

2

クエリはそれほど複雑ではありません。subscription_types確かに数百行以下の小さなテーブルであるテーブルには、結合が 1 つしかありません。

  • インデックスはどこにありますか? クエリを改善する最善の方法は、フィルタリングするフィールドに、、、、などのインデックスを作成することですactivecountry_codestate_codesearchable
  • で外部キーを作成しましたusers_data.subscription_idか? それについても索引が必要です。
  • ForceIndex最適なインデックスを RDBMS に決定させます。
  • subscription_types.searchable='1'行が不一致の対応を削除するため、Left Join も役に立ちません。
  • の順序はsearch_priority、この列にもインデックスが必要であることを意味します
  • でのフィルタリングによりHAVING、インデックスが使用されなくなる場合があります。これらのフィルタを に配置する必要はありませんHAVING。テーブル スキーマを理解している場合、これは実際にはフィルター処理された集計ではありません。

テーブルには 100 万行が含まれていますが、制限なしで返される行数はどれくらいですか? 適切なインデックスを使用すると、クエリは 1 秒未満で実行されるはずです。

SELECT ...
FROM `users_data`
    INNER JOIN subscription_types 
        ON users_data.subscription_id = subscription_types.subscription_id 
WHERE users_data.active='2' 
  AND users_data.country_code='US' 
  AND users_data.state_code='NY'
  AND subscription_types.searchable='1'
  AND (distance <= '50' OR location_limit='all' OR users_data.nationwide='1')
GROUP BY users_data.user_id 
ORDER BY subscription_types.search_priority ASC, distance ASC 
LIMIT 0,10
于 2013-10-10T09:17:59.747 に答える