Массовая вставка с pyodb c + SQL Сервер медленный с None / Nan + обходной путь - PullRequest
2 голосов
/ 14 апреля 2020

Проблема заключается в попытке загрузить данные на сервер SQL и получить скорость 122 строки в секунду (17 столбцов). Я решил опубликовать проблему здесь вместе с обходным путем в надежде, что кто-то знает окончательный ответ.

Самая важная тема, которую я нашел, была, но проблема существенно отличается и все еще без ответа: pyodb c - очень низкая скорость массовой вставки

Это простой сценарий, в котором я пытаюсь загрузить CSV из 350K строк в пустую SQL таблицу сервера, используя Python. Попробовав один из самых популярных способов, то есть прочитайте его как pandas DataFrame, создайте механизм sql_alchemy с fast_executemany = True и используйте метод to_ sql () для сохранения в базе данных. Я получил 122 строки в секунду, что недопустимо.

Как упоминалось в других потоках, этого не происходит в PostgreSQL или Oracle, и я могу добавить, что в MariaDB этого не происходит. Поэтому я попробовал другой подход, используя pyodb c cursor.executemany (), чтобы увидеть, есть ли ошибка в pandas или sql_alchemy. Та же скорость.

Следующим шагом было создание синтетических c данных, чтобы повторить проблему, чтобы сообщить об ошибке ... и, к моему удивлению, сгенерированные данные были около 8000 записей в секунду. WTF? В данных использовался тот же тип данных (очевидно), что и в CSV.

После нескольких недель попыток попробовать разные вещи, я решил изучить сам pydob c. На сайте pyodb c github dev я нашел интересную информацию по адресу https://github.com/mkleehammer/pyodbc/wiki/Binding-Parameters, особенно в Writing NULL и в Решения и обходные пути секции.

Действительно, 3 из 17 полей в первой строке CSV были преобразованы в 'Nan' в Pandas или в None вручную. К моему удивлению после замены этих None / Nan / NULL действительными значениями на FIRST LINE ONLY , скорость была увеличена до 7-8000 записей / с. Обратите внимание, что я не изменил ни один из None / Nan в последующих строках, только в первой.

Кто-нибудь понимает, почему это происходит? Есть ли более элегантное решение, чем переключение для замены None / Nan на допустимое значение?

ОБНОВЛЕНИЕ : Кажется, на странице Github есть несколько связанных проблем, и все они указывают на то же самое вопрос. Для справки: https://github.com/mkleehammer/pyodbc/issues/213. Нить относительно старая, с 2017 года, но, похоже, проблема в том, как бороться с None / Nan, сохраняется.

...