MySQL:如何加快加入?

时间:2013-02-26 15:31:11

标签: mysql join

我有两张桌子,我需要加入他们。不幸的是,我没有可以使用的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)))

我知道这不是最快的方法,但有没有办法将这一点提高一点?或者也许我现在想不到的解决方法?

谢谢!

5 个答案:

答案 0 :(得分:2)

索引firstname和lastname列将是一个开始。

首先,虽然我会在前面使用EXPLAIN运行你的查询,看看是否有你可能已经拥有的任何索引并且正在使用它们实际上可能没有被使用。

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

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

答案 1 :(得分:1)

您可以在名字和姓氏之间添加“和”,以避免连续。你也可以在这些列(firstname和lastname)上使用索引,以便加快速度(特别是如果你经常使用比较)。

join sales_flat_order_address sfoa on    
trim(sfoa.firstname) = trim(so.firstname) and trim(sfoa.lastname) = trim(so.lastname)

答案 2 :(得分:1)

此查询基本上是在表上进行交叉连接,然后匹配条件。要解决此问题,您可以:

  1. 在每个名为全名的表中添加一个新列。
  2. 为此赋予以下内容的价值: concat(lower(trim(firstname)), lower(trim(lastname)))
  3. 建立值的索引。
  4. 实际上,你只能在其中一个表上执行此操作,MySQL将使用索引进行比较(仍然需要在第一个表上进行全表扫描。

    您还可以拥有“全名”表,并使用每个表中的外键来获取全名。

    独立索引名称不会影响查询。这些名称是在函数内部访问的,这通常会关闭使用索引的能力。

答案 3 :(得分:1)

你可以尝试使用它:

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

当然,您可以尝试在两个表中对firstnamelastname编制索引。

答案 4 :(得分:0)

至少应该在两个表中的firstname和lastname上创建索引。另外,对您的查询运行说明。这可能会显示效率低下。