0

2 つのテーブルがあり、それらに参加する必要があります。残念ながら、使用できる ID がありません。唯一の基準は、いくつかの varchar 列です。これは、結合の「オン」部分です。

join sales_flat_order_address sfoa on    
   concat(lower(trim(sfoa.firstname)), lower(trim(sfoa.lastname))) = concat(lower(trim(so.firstname)), lower(trim(so.lastname)))

これが最速の方法ではないことはわかっていますが、これをもう少しスピードアップする方法はありますか? それとも、今は考えられない回避策ですか?

ありがとう!

4

5 に答える 5

2

firstname 列と lastname 列のインデックス作成から始めます。

まず最初に、クエリの前に EXPLAIN を付けてクエリを実行し、実際には使用されていない可能性のある、既に使用されていると思われるインデックスがあるかどうかを確認します。

第二に、varchar での結合は、たとえば int での結合と比較して「超」高速になることは決してありません。

http://dev.mysql.com/doc/refman/5.5/en/explain.html

于 2013-02-26T15:34:18.647 に答える
1

連結を避けるために、名と姓の間に「and」を追加できます。また、これらの列 (名と姓) にインデックスを使用して、処理を大幅に高速化することもできます (特に、比較を頻繁に使用する場合)。

join sales_flat_order_address sfoa on    
trim(sfoa.firstname) = trim(so.firstname) and trim(sfoa.lastname) = trim(so.lastname)
于 2013-02-26T15:35:18.470 に答える
1

このクエリは基本的に、テーブルでクロス結合を実行してから、条件に一致させます。これを修正するには、次のことができます。

  1. full name という名前の新しい列を各テーブルに追加します。
  2. これに次のような値を与えます: concat(lower(trim(firstname)), lower(trim(lastname))).
  3. 値にインデックスを作成します。

実際には、テーブルの 1 つだけでこれを行うことができ、MySQL は比較のためにインデックスを使用します (最初のテーブルで完全なテーブル スキャンが必要です。

「フル ネーム」テーブルを作成し、これらの各テーブルの外部キーを使用してフル ネームを取得することもできます。

名前を個別にインデックス付けしても、クエリには影響しません。名前は関数内でアクセスされているため、通常、インデックスを使用する機能がオフになっています。

于 2013-02-26T15:35:24.107 に答える
1

これを使用してみることができます:

ON trim(sfoa.firstname) = trim(so.firstname)
   AND trim(sfoa.lastname) = trim(so.lastname)

もちろん、両方のテーブルでインデックスfirstnameを作成することもできます。lastname

于 2013-02-26T15:37:56.670 に答える
0

少なくとも、両方のテーブルで名と姓にインデックスを作成する必要があります。また、クエリで Explain を実行します。それはあなたの非効率性を示すことができます。

于 2013-02-26T15:33:46.067 に答える