2

私はSQLの第一人者から遠く離れており、実行しようとしています:

SELECT `apps`.* FROM `apps` 
 INNER JOIN `similars` 
 ON (`apps`.id = `similars`.similar_app_id OR `apps`.id = `similars`.app_id) 
WHERE (`similars`.app_id = 542 
 OR `similars`.similar_app_id = 542) 
 AND apps.id <> 542 
ORDER BY field(`similars`.app_id, 542) desc LIMIT 6

order by を使用すると、order by を使用しない場合よりも 20 倍遅くなります。

explain extended 
SELECT DISTINCT `apps`.* 
  FROM `apps` 
  INNER JOIN `similars` 
    ON (`apps`.id = `similars`.similar_app_id 
    OR `apps`.id = `similars`.app_id) 
  WHERE (`similars`.app_id = 542 
    OR `similars`.similar_app_id = 542) AND apps.id <> 542 
  ORDER BY `similars`.app_id - 542 desc

私に与えます:

+----+-------------+----------+-------------+----- -------------------------------------------------- ------------+-------------------------------------------------+- --------+------+-------+----------+--------------- -------------------------------------------------- ------------------------------+
| | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 フィルタリングされた | エクストラ |
+----+-------------+----------+-------------+----- -------------------------------------------------- ------------+-------------------------------------------------+- --------+------+-------+----------+--------------- -------------------------------------------------- ------------------------------+
| | 1 | シンプル | 類似品 | インデックスマージ | index_app_id_and_similar_app_id,index_app_id,index_similar_app_id | index_app_id,index_similar_app_id | 5,5 | ヌル | 241 | 100.00 | union(index_app_id,index_similar_app_id); の使用 where を使用します。一時的な使用; ファイルソートの使用 |
| | 1 | シンプル | アプリ | 範囲 | プライマリ | プライマリ | 4 | ヌル | 21493 | 100.00 | where を使用します。結合バッファーの使用 |
+----+-------------+----------+-------------+----- -------------------------------------------------- ------------+-------------------------------------------------+- --------+------+-------+----------+--------------- -------------------------------------------------- ------------------------------+

app_id、similar_app_id、およびそれらの複合体のインデックスのすべての組み合わせを試しました。

ヒントやコツはありますか?

ありがとう

4

3 に答える 3

0

は関数を呼び出しているためFIELD()、MySql はインデックスや並べ替えを使用できません。ドキュメントから:

場合によっては、MySQL がインデックスを使用して ORDER BY を解決できないことがあります...キー列名以外の用語を含む式で ORDER BY を使用している

ORDER BY関数を使用しないように書き換えます。たとえば、 aapp_id = 542を一番上に表示したい場合は、次のように記述できます。

ORDER BY `similars`.app_id = 542 DESC
于 2011-03-21T04:20:30.973 に答える
0

インデックス化されていないフィールドによるソートに関係なくLIMIT-あなたの場合、ソートする値の計算を行うと、常に時間がかかります...

注文のために控除542をスキップし、app_idのインデックスを追加します

于 2011-03-21T02:03:53.383 に答える
0

試してみることのできることの 1 つは、WHERE 句を JOIN 条件に移動することです。mysql は、where 句を使用してフィルタリングする前に結合を試みることがあると思います。これはあなたが試すことができるものであり、実際に役立つかどうかはわかりません.

SELECT `apps`.* FROM `apps` 
 INNER JOIN `similars` 
 ON (`apps`.id = `similars`.similar_app_id OR `apps`.id = `similars`.app_id) 
  AND (
       (`similars`.app_id = 542 OR `similars`.similar_app_id = 542) 
       AND apps.id <> 542
  ) 
ORDER BY field(`similars`.app_id, 542) desc LIMIT 6
于 2011-03-21T02:09:18.580 に答える