1

以下のクエリは非常に遅く、最適化できることがわかっています。0.0479秒かかりますが、これは計算フィールドでソートされているためです。selectステートメントで、テーブルの主キーであるadvert_id列を選択します。以下のクエリを修正すると、advert_idの主キーを選択せず​​に、他のすべてを同じままにしておくと、実行に0.0098秒しかかかりません。

SELECT adverts.advert_id, round( sqrt( ( ( (adverts.latitude - '51.558430') * (adverts.latitude - '51.558430') ) * 69.1 * 69.1 ) + ( (adverts.longitude - '-0.0069345') * (adverts.longitude - '-0.0069345') * 53 * 53 ) ), 1 ) as distance
FROM adverts
WHERE (adverts.status = 1) AND (adverts.approved = 1) 
AND (adverts.latitude BETWEEN 51.2692837281 AND 51.8475762719) 
AND (adverts.longitude BETWEEN -0.472015213613 AND 0.458146213613) 
having (distance <= '20') 
ORDER BY distance ASC 
LIMIT 0,10

最初のクエリで、explainは、以下の「sall」インデックスを使用していると述べていますが、追加の列は「Usingwhere;」に設定されています。filesortを使用する'。

advert_idを選択しないようにクエリを修正すると、explainは「sall」インデックスを使用していると言いますが、追加の列は「Usingwhere;」に設定されます。インデックスを使用します。filesortを使用する'。

'sall'インデックスには、次の列が含まれます。

ステータス承認済み緯度経度

別のインデックスを作成しようとしましたが、ステータスの前にadvert_idを追加して、最初のクエリでこれを使用してより高速になることを期待しましたが、インデックスの使用を強制すると、さらに遅くなりました。

4

1 に答える 1

2

advert_id をインデックスの先頭ではなく末尾に追加します。

これにより、インデックスのみを使用してクエリを処理できますが (「インデックスを使用する」という意味です)、インデックスが既に提供している効率的な検索を妨げることはありません。

また、Jim Garrison が指摘したように、クエリの HAVING 句の前に「GROUP BY adverts.advert_id」を追加する必要があります。

于 2012-09-30T23:01:35.103 に答える