我试图使用levhenstein修改此查询。我的问题是我可以在内连接查询中添加我的条件,而不是在查询的位置。
这是我的实际查询:
SELECT
registrosImportados.id, TVC.NOMBRETVC,
VIACU.NOMBREVIACU, CUT.GLOSA,
registrosImportados.direccion,
dbo.fn_LevenshteinDistance(registrosImportados.direccion, VIAIU.NOMBREVIAIU, 5)
FROM
ACOPIOCI
INNER JOIN
TVC ON ACOPIOCI.IDTVC = TVC.IDTVC
INNER JOIN
VIACU ON ACOPIOCI.IDVIACU = VIACU.IDVIACU
INNER JOIN
VIAIU ON ACOPIOCI.IDVIAIU = VIAIU.IDVIAIU
INNER JOIN
CUT ON ACOPIOCI.IDCUT = CUT.IDCUT
INNER JOIN
registrosImportados ON CUT.CUT = registrosImportados.cut
WHERE
dbo.fn_LevenshteinDistance(registrosImportados.direccion, VIAIU.NOMBREVIAIU, 5) = (SELECT MIN(M.DISTANCIA)
FROM
(SELECT dbo.fn_LevenshteinDistance(registrosImportados.direccion, VIAIU.NOMBREVIAIU, 5) AS DISTANCIA
FROM ACOPIOCI
INNER JOIN VIAIU ON ACOPIOCI.IDVIAIU = VIAIU.IDVIAIU
WHERE ACOPIOCI.IDCUT = CUT.IDCUT) AS M
)
AND ACOPIOCI.IDCUT = CUT.IDCUT
这就是我想要做的事情:
SELECT
VIACU.NOMBREVIACU, registrosImportados.DIRECCION,
dbo.fn_LevenshteinDistance(registrosImportados.direccion, VIAIU.NOMBREVIAIU, 2) DIST
FROM
ACOPIOCI
INNER JOIN
TVC ON ACOPIOCI.IDTVC = TVC.IDTVC
INNER JOIN
VIACU ON ACOPIOCI.IDVIACU = VIACU.IDVIACU
INNER JOIN
VIAIU ON ACOPIOCI.IDVIAIU = VIAIU.IDVIAIU
INNER JOIN
CUT ON ACOPIOCI.IDCUT = CUT.IDCUT
INNER JOIN
registrosImportados ON CUT.CUT = registrosImportados.cut
INNER JOIN
(SELECT
MIN(dbo.fn_LevenshteinDistance(registrosImportados.direccion, VIAIU.NOMBREVIAIU, 2)
) AS MINDIST) M ON registrosImportados.DIST = M.MINDIST
但它不起作用。我的想法是在我的查询中获得性能。
答案 0 :(得分:2)
此问题的最佳解决方案是将Levenshtein距离计算结果存储在表中,可能作为计算列,以便更新是自动的,这样您就可以在该值上放置索引。在你这样做之前,你会遇到性能问题。
也就是说,我们至少可以对查询进行一些改进。距离计算当前在查询中使用了3次:对于选择列表,在where子句中,以及计算最小距离。我希望Sql Server足够聪明,可以对SELECT和WHERE使用相同的计算(你应该通过检查执行计划来验证这一点),但我怀疑它是否能够计算最小距离。
这意味着查询有效地执行了两次:一次用于基础数据,一次用于计算最小距离;几乎所有来自基础数据查询的工作都必须重复。我们可以通过从查询的主要部分(包括levenshtein距离计算)中将未过滤的结果拉入临时表或CTE(the best option depends mainly on the size of the data),然后选择,从而加快查询速度。从该表/ CTE。这将有助于Sql Server知道如何避免为每个可能的结果记录计算两次距离。
对于此示例,我将使用CTE选项:
With Data As
(
SELECT
r.id, b.NOMBRETVC, c.NOMBREVIACU,
CUT.GLOSA, r.direccion,
dbo.fn_LevenshteinDistance(r.direccion,i.NOMBREVIAIU,2) As Distance
FROM ACOPIOCI a
INNER JOIN TVC b ON a.IDTVC = b.IDTVC
INNER JOIN VIACU c ON a.IDVIACU = c.IDVIACU
INNER JOIN VIAIU i ON a.IDVIAIU = i.IDVIAIU
INNER JOIN CUT ON a.IDCUT = CUT.IDCUT
INNER JOIN registrosImportados r ON CUT.CUT = r.cut
)
SELECT id, NOMBRETVC, NOMBREVIACU
FROM Data
WHERE Distance = (SELECT MIN(Distance) FROM DATA)
如果CTE中有很多行(超过你的可用内存量),你可以使用临时表或表变量做得更好。