Сопоставление сущностей в SQL Server, чтобы заменить итерационный скрипт Python


У меня есть SQL (MSSQL-сервер) база данных ~22 млн компаний (так называемый target_db в моем коде). Например:

+-----------------------+----------------+-----------+
|     CompanyName       |    ReFcode     | ID_number |
+-----------------------+----------------+-----------+
| Mercedes Benz Limited | Germany        |     12345 |
| Apple Corporation     | United States  |     67899 |
| Aunt Mary Butcher     | United Kingdom |     56789 |
+-----------------------+----------------+-----------+

Потом, у меня есть еще один список компаний (называемых ввод в моем примере), и я хотел бы назначить ID_number на основе примерной название компании совпадают. Размер моего образца составляет 1000 компаний, но может быть гораздо больше.

+--------------------+----------------+
|      name          |    ReFcode     |
+--------------------+----------------+
| Mercedes Benz Ltd. | Germany        |
| Apple Corp.        | United States  |
| Butcher Aunt Mary  | United Kingdom |
| Volkswagen Gmbh    | Germany        |
+--------------------+----------------+

Я написал скрипт на Python, который выполняет следующие действия для каждой из компаний в моем примере:

  1. Подключение к базе данных и отфильтровать target_db чтобы получить только имена, которые начинаются с той же 3 буквы, имеют одинаковую длину (+- 7 символов) и его. Разница 4
  2. Рассчитать Левенштейна со всех возможных совпадений (используя fuzzywuzzy библиотека)
  3. Выбрать матч с наибольшим сходством

Это, в основном, работали хорошо и справился с этой задачей примерно за 6 минут. Я сделал некоторые профилирования и заметил, что 5 минут и 30 секунд было потрачено на подключение к БД (в каждой итерации цикла), выполнение запроса и получение результатов. Остальные вычисления подобия. Который я нашел довольно удивительно.

Я думал, что я мог бы сэкономить время и повысить производительность, делаем полностью процесс в SQL, так что я начал писать этот запрос:

SELECT distinct input.name, 
                target_db.CompanyName, 
                input.Country, 
                input.ReFcode, 
                [dbo].[edit_distance](input.name, target_db.CompanyName) as levenshtein
FROM dbo.Sample as input
JOIN dbo.Company as target_db
on 
    (input.ReFcode = target_db.Refcode and 
    LEFT(input.name, 3) = LEFT(target_db.CompanyName, 3) and
    SOUNDEX(input.name)=SOUNDEX(target_db.CompanyName))
WHERE ABS( LEN(input.name) - LEN(target_db.CompanyName)) <= 7

ORDER BY levenshtein asc

Тогда я бы взял матч с самой низкой EditDistance (Левенштейна) ниже определенного порога. Это работает, но теперь этот процесс занимает почти 30 минут. Что я делаю не так? Любые предложения о том, как улучшить его?



211
2
задан 10 февраля 2018 в 10:02 Источник Поделиться
Комментарии