基于字符串的部分匹配加入MySQL表

时间:2017-02-03 14:37:07

标签: mysql database

我想要加入两个表 DomainLinks分别有1k行和700k行

create table Domain (url varchar(255), tag varchar(255));
create table Links (ShortURL varchar(255), LongURL varchar(255));

输出应该在Domain.url中找到的所有字符串Links.LongURL的部分匹配时连接,结果应该从Links表返回700k行,其中找不到匹配项null 1}}

尝试了threadhere

中的以下内容
SELECT ShortURL,LongURL,tag
FROM Links fulljoin Domain 
ON Links.LongURL LIKE concat('%', Domain.url, '%');

3 个答案:

答案 0 :(得分:1)

这将是一项耗时的操作。您的查询是在正确的轨道上,但正确的语法是:

SELECT ShortURL, l.LongURL, tag
FROM Links l LEFT JOIN
     Domain d
     ON l.LongURL LIKE concat('%', d.url, '%');

那就是说,使用你的两个表,这个查询需要一段时间。它需要使用like进行大约700,000,000次比较。没有简单的方法可以加快查询速度。

答案 1 :(得分:1)

要返回所有Links,无论是否匹配Domain,您都可以使用LEFT OUTER JOIN

要确保每个Links行只返回一次,您应该GROUP BY Links列,只返回一个Domain(使用像{{1}这样的聚合函数如果给定MIN()行有多个MAX()匹配,则为{}}或Domain

这样的事情:

Links

您现有的select Links.ShortURL, Links.LongURL, min(Domain.tag) from Links left outer join Domain on Links.LongURL like concat('%', Domain.url, '%') group by Links.ShortURL, Links.LongURL 语句会非常慢,无法从LIKE上的索引中受益。你是如何存储URL和域的?如果它们具有一致的前缀,例如所有Links.LongURLLinks.LongURL值都以Domain.url开头,那么您可以在https://上添加索引,摆脱前导通配符,并使查询更快,如下所示:

Links.LongURL

答案 2 :(得分:0)

如果DOMAIN名称每次都在字符串的开头处开始,您可以像这样加速。 MySQL可以使用INDEX:

SELECT ShortURL,LongURL,tag
FROM Links fulljoin Domain 
ON
  Links.LongURL LIKE concat(Domain.url, '%')
OR
  Links.LongURL LIKE concat('www.',Domain.url, '%');