1

2 つのテーブルを持つ MySQL データベースがあります。

表 A:

  • 番号
  • 位置

表 B:

  • 呼び出しコード
  • 市外局番
  • 位置

最初は、テーブル A に約 60,000 のエントリがあり、最初は Location 列が空です。テーブル BI には、多くのエリア コー​​ド、コーリング コード (1, 011)、および世界のそれぞれの場所を含む約 250,000 以上のエントリがあります。私が欲しいのは、テーブル A の場所の列に番号の場所を入力する FAST 方法です。

たとえば、テーブル A の最初のエントリが (17324765600, null) の場合、テーブル B を読み込んでその番号の場所を取得したいとします。現在、次のクエリで数値の場所を取得しています。

SELECT b.location
FROM 
  tableB b
  LEFT JOIN tableA a
     ON a.number LIKE CONCAT(b.calling_code, b.code, '%')
ORDER BY CHAR_LENGTH(b.code) DESC
LIMIT 1;

これにより、適切な場所が得られます(失敗する可能性があるとは思いませんが..)。問題は、パフォーマンスに関してこの方法がうまくいかないことです。すべての 50k 番号をループすると

更新 1

予想される出力を含むサンプル データをいくつか入れさせてください: サンプル テーブル A:

番号の場所
17324765600 ヌル
01134933638950ヌル
0114008203800ヌル
…60k レコード + 現時点で..

サンプル表 B:

calling_code コードの場所
1 7324765 米国-ニュージャージー州
011 34933 スペイン
011 400820 中国
…現時点で 250,000 件以上のレコード

処理後に期待される出力: 表 A:

番号の場所
17324765600 米国-ニュージャージー州
01134933638950 スペイン
0114008203800 中国

私が思いついた最高のものは、次の更新ステートメントです。

UPDATE tableA a JOIN tableB b ON a.location LIKE CONCAT(b.calling_code, b.code, '%') SET a.location = b.location

もちろん、ここでは常にコードの最長のプレフィックスを返すかどうかはわかりません。たとえば、上記の表に 73247XX で始まる別のコードがあった場合、コードがアイオワ用であるとしましょう (例として)。クエリが常に最長のコードを返すかどうかわからないので、ここでも助けが必要です。

サンプルが役立つかどうか教えてください。

データベース構造の .SQL: ダウンロード

更新 2:

私はこれを次の方法で行うことを考えています:

テーブル AI にデータを挿入する前に、テーブル B を CSV にエクスポートし、市外局番で並べ替えることを考えています。これにより、テーブル A のエントリの配列用と csv 用の 2 つのポインタを、両方とも市外局番で並べ替えることができます。そうすれば、一種の並列検索を行い、PHP でエントリの場所を入力することができ、MySQL でこれを行う必要はありません。

このアプローチがより良いオプションのように思われる場合はお知らせください。そうであれば、テストして回答を公開します。

4

3 に答える 3

0

250000 レコードの結合が 1 つしかなく、それほどストレスはありません。検索列と に対して適切なインデックスを作成する必要がありますfine tune your mysql server。設定するgood indexing & server variables wellことで、問題を簡単に解決できます。クエリを適切に最適化します。通常、多くの結合と多くの文字列比較があると問題が発生します。

このようなクエリが必要だと思います-

UPDATE a SET a.location = ( 
                            SELECT location from b 
                            WHERE a.number LIKE CONCAT(b.calling_code, b.area_code, '%') 
                            ORDER BY LENGTH(CONCAT(b.calling_code, b.area_code, '%')) desc 
                            limit 1
                          );
于 2015-07-03T19:36:32.840 に答える