0

私はこのような構造のデータベースを持っています:

  • t_person(idp、idcity、name、addr、tels、zip、desc、premium)
  • t_city(idcity、idcountry、cityname)
  • t_country(idcountry、countryname)

非常に一般的な「ライブ検索」(グーグルのような)が欲しい:

SELECT p.name, p.addr, p.zip, p.desc, c.cityname, x.countryname, 
MATCH (p.name, p.addr, p.zip, p.desc) 
AGAINST ('fred* tall* 94620*' IN BOOLEAN MODE) as score
FROM t_person p
INNER JOIN t_city c ON c.idcity = p.idcity
INNER JOIN t_country x ON x.idcountry = c. idcountry 
WHERE MATCH (p.name, p.addr, p.zip, p.desc) 
AGAINST ('fred* tall* 94620*' IN BOOLEAN MODE)
AND x.idcountry = 43 -- (i.e USA)
ORDER BY score DESC, p.name ASC, p.premium DESC

1000〜1500行しかない場合、このクエリは約0.011秒で実行されますが、30000行以上ある場合は、約1.2秒以上かかります(データジェネレーターでテストしました)。問題は、evey country(1 --- n)の人用に新しいテーブルを作成すると、次のようになります
。t_person_uk、t_person_usa、t_person_spain、それぞれ1500行の場合、この方法で検索が非常に高速になると思います。
PD、検索するAJAX呼び出しを行う前に、すでに0.25秒のタイムアウトがあります。
ありがとう、さようなら。

4

2 に答える 2

0

私の最初の提案は、SQL を使用して説明列のテキストを検索しないことです。大量のテキストがそこに座っていると思われるため、トラフィックが多い状態で DB を酷使しすぎることを懸念している場合。特に、列の優先度チェーンのはるか下にあるためです。

しばらく考えてみたところ、これが最大の処理負荷であることがほぼ 100% 確信できました。ブラウザで結果をどのように提供しているかはわかりませんが、たとえば python を使用して文字列を直接検索すると、間違いなくより良い結果が得られます。

それを超えて、私はあなたに何を言うべきかわかりません。あなたが言っているようにテーブルを分割し、プログラムでアクセスすることができます。もしそうするなら、集計テーブルを作成することをお勧めします。しかし、私はその考えが本当に好きではありません。

于 2012-06-05T08:18:03.203 に答える
0

これはあなたの質問に対する直接的な回答ではありませんが、コメントするには少し長すぎます。

一般に、これらのタイプの検索は、MySQL ではなくフルテキスト インデックス検索エンジンを使用して構築されています。全文検索エンジンはMATCH、MySQL の標準よりも多くの可能性を提供します。

たとえば、部分一致を実行したり、距離で並べ替えられた結果を返したり、自動提案や自動補完を行うことができます。MySQL が提供するのは、2 つまたは 3 つのモードを持つ 1 つの一致する関数という最低限の機能だけです。

フルテキスト インデックス作成の良い例は、Lucene の上に構築されたApache Solrです。

また、 geonamesで無料の非常に包括的な地理データのデータベースを利用できます。

うまくいけば、これはあなたにとってあまり話題から外れていません:)

于 2012-06-05T03:33:07.260 に答える