2

PHP と jQuery を使用してライブ検索を実行し、2 つのテーブルcities(ほぼ 300 万行) とcountries(数百行) から都市と国を選択する必要があります。

しばらくの間、検索をサポートしていないMyISAMため、テーブルを使用することを考えていましたが、それは方法ではないと判断しました (頻繁なテーブルのクラッシュ、他のすべてのテーブルなどであり、MySQL 5.6 以降ではインデックスのサポートも開始されます)。citiesInnoDBFULLTEXTInnoDBInnoDBFULLTEXT

そのため、現在もまだ MySQL 5.1 を使用しています。ほとんどの都市は 1 単語のみ、または最大 2 ~ 3 単語で構成されているため、たとえば「New York」では、「New York」を意味する場合、ほとんどの人は「York」を検索しません。 . city_realそのため、列 (varchar) にインデックスを付けただけです。

次のクエリ(私はさまざまなバージョンでそれを試しました。 anyJOINと without ORDER BY、 withUSE INDEXを使用しても、FORCE INDEX代わりに LIKE を試しましたが、別の投稿では = の方が高速で、ワイルドカードが最後にのみある場合は問題ありませんそれを使用する)、EXPLAIN常に「どこで使用して、ファイルソートを使用して」と言います。クエリの平均時間は約 4 秒です。これは、ライブ検索では少し遅いことを認めなければなりません (ユーザーがテキスト ボックスに入力し、都市や国の候補を表示します)...

ライブ検索 (jQuery ajax) は、ユーザーが 3 文字以上入力した場合に検索します...

SELECT ci.id, ci.city_real, co.country_name FROM cities ci LEFT JOIN countries co ON(ci.country_id=co.country_id) WHERE city_real='cit%' ORDER BY population DESC LIMIT 5

PRIMARYonci.idINDEXonがありci.city_realます。MySQL がインデックスを使用しない理由はありますか? または、どうすればクエリを高速化できますか? または、他にどこに設定する必要がありINDEXますか?

よろしくお願いいたします。


説明の出力は次のとおりです

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  ci  range   city_real   city_real   768 NULL    1250    Using where; Using filesort
1   SIMPLE  co  eq_ref  PRIMARY PRIMARY 6   fibsi_1.ci.country_id   1    
4

2 に答える 2

3

WHERE city_real LIKE 'cit%'ではなく、を使用する必要がありますWHERE city_real='cit%'

等しい (=) の代わりに LIKE を試してみましたが、別の投稿では = の方が高速で、ワイルドカードが最後にのみある場合は使用しても問題ないと述べています

これは間違っています。=はワイルドカードをサポートしていないため、間違った結果が得られます。

または、どうすればクエリを高速化できますか?

country_id両方のテーブルにインデックスがあることを確認してください。EXPLAIN SELECT ...さらにヘルプが必要な場合は、の出力を投稿してください。

于 2012-04-29T17:47:01.827 に答える
1

keyクエリは、説明出力のフィールドに見られるようにインデックスを使用します。filesort を使用する理由は順序付けであり、おそらくフィールド (city_real、population) の 1 つである where を使用する理由は null 値を許可します。

于 2012-04-30T18:25:17.690 に答える