0

我有 2 张桌子,我需要加入它们。不幸的是,我没有可以使用的 id,唯一的标准是一些 varchar 列。这是连接的“on”部分:

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 运行您的查询,看看是否有任何您可能已经拥有并认为正在使用的索引实际上可能没有被使用。

其次,与加入 int 相比,加入 varchar 永远不会“超级”快。

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. 在每个表中添加一个名为全名的新列。
  2. 给它一个类似的值: concat(lower(trim(firstname)), lower(trim(lastname))).
  3. 在该值上建立索引。

实际上,您可以只对其中一个表执行此操作,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

至少,您应该在两个表中的 firstname 和 lastname 上创建一个索引。此外,对您的查询进行解释。这可以显示您的效率低下。

于 2013-02-26T15:33:46.067 回答