Сначала вам придется скрестить две таблицы (m и n дает m x n сравнений) и сравнить, чтобы найти совпадения - другого простого способа на самом деле не существует.
Однако, с мета-пониманием данных, их интерпретации и ваших целей, если вы сможете каким-то образом отфильтровать свой набор, чтобы довольно легко исключить элементы из перекрестного соединения, это помогло бы - особенно если есть что-то, что должно быть точным сопоставить или любым способом разделить данные так, чтобы элементы в разных разделах никогда не сравнивались (т. е. сравнение местоположения в США и Европе всегда имело бы ранг совпадения 0)
Я бы сказал, что вы можете использовать Lat и Long для полного исключения, если они различаются на определенную величину, но похоже, что они используются для улучшения рейтинга совпадений, а не для отрицательного исключения предметов из ранжирования совпадений.
А скалярные функции (ваши FuzzyMatches), вызываемые повторно (как в перекрестном соединении с многомиллионными строками), чрезвычайно дороги.
Мне кажется, что вы могли бы извлечь первое совпадение и другое внутреннее в вашем перекрестном соединении (и, если возможно, встроенном, а не как UDF), чтобы оптимизатор запросов мог их несколько оптимизировать в сочетании с перекрестное соединение вместо черного ящика, называемого mxn times.
Другая возможность заключается в предварительном извлечении только отдельных пар телефонных номеров, пар почтовых индексов и т. Д.
SELECT Postcode1, Postcode2, dbo.FuzzyLogicStringMatch(Postcode1, Postcode2) AS MatchRank
FROM (
SELECT DISTINCT Postcode AS Postcode1
FROM Table1
) AS Postcodes1
CROSS JOIN
(
SELECT DISTINCT Postcode AS Postcode2
FROM Table2
) AS Postcodes2
Если ваша функция симметрична, вы можете еще больше сократить это пространство, в котором вызывать UDF, с некоторой дополнительной работой (проще, если таблица является самосоединением, вы просто используете верхний правый треугольник).
Теперь у вас есть минимальный набор сравнений для вашего скалярного UDF, который нужно вызвать. Поместите этот результат в таблицу, индексированную по двум столбцам.
Вы можете сделать подобное для всех ваших наборов параметров UDF. Если определение функции не меняется, вам нужно только добавлять новые комбинации в вашу таблицу с течением времени, превращая дорогой скалярный вызов функции в поиск таблиц на относительно медленных растущих данных. Вы даже можете использовать оператор CASE для отклика на встроенный вызов UDF, если в таблице поиска нет записи - так что вы можете решить, сохранять ли таблицы поиска полными или нет.