вставка нулей намного медленнее, чем пустых строк, при использовании pyspark для записи фрейма данных на sql server с помощью jdbc

#sql-server #jdbc #apache-spark #pyspark #apache-spark-sql

#sql-server #jdbc #apache-spark #pyspark #apache-spark-sql

Вопрос:

Я работаю над databricks / spark (1.6.2, Python) для импорта фрейма данных на MS SQL Server (2014) в виде таблицы. Фрейм данных состоит примерно из 100 миллионов строк и 20 столбцов, а половина столбцов — строки. Более конкретно, 2 cols из них являются NVARCHAR, остальные — VARCHAR .

Производительность записи на SQL Server трудно объяснить в отношении решения пустых строк. Запись занимает около 10 минут или около того, если пустые строки сохраняются «как есть», однако время записи будет намного больше (> 10 часов) после преобразования пустых строк в нули. Под «после» я подразумеваю, что процедура преобразования выполняется быстро и выходит за рамки.

Код для генерации фрейма данных,

 df = sqlContext.read.format('com.databricks.spark.csv')
               .options(header='false', inferSchma=None, delimiter='t', quote='', 
                        treatEmptyValuesAsNulls='true') # covert if true
               .load(csvfile, schema=schema)
df.write.jdbc(jdbcUrl, "tableOfMSSQL")
  

Таблица в SQL server имела согласованную схему с фреймом данных, и внешние ключи не были настроены. Я не уверен, что вызывает огромную разницу.

Вот несколько гипотез:

  1. JDBC обрабатывает пустые строки и нули совершенно по-разному в отношении вставки. (нет доказательств)
  2. Фрейм данных имеет кодировку UTF-8, в то время как NVARCHAR SQL Server имеет кодировку UTF-16LE. Вставка нулей может быть намного дороже, чем пустых строк в NVARCHAR cols. (доказательство: проверено на подмножестве данных, NVARCHAR col которых все специальные значения, для вставки нулей требуется гораздо больше времени, чем для пустых строк)

Разумны ли эти гипотезы? И каково решение, если это так?

Комментарии:

1. JDBC — это просто набор интерфейсов, он не имеет — за исключением некоторых методов по умолчанию в Java 8 и некоторых поддерживающих классов — собственной реализации. Поведение может сильно зависеть от драйвера (или даже версии драйвера). Я думаю, что этот вопрос граничит с слишком широким, потому что вы не определили, действительно ли проблема связана с драйвером JDBC (например, устранили ли вы вероятность того, что накладные расходы связаны с тем, как spark вместо этого использует JDBC), и это может быть невозможно без глубоких знаний и исследований (пробныхи ошибка).

2. @MarkRotteveel Спасибо, так вы предполагаете, что мне нужно сначала лучше понять детали реализации этого конкретного JDBC?

3. Если вы хотите знать, на кого возлагать вину, вам, вероятно, потребуется использовать драйвер JDBC напрямую, без использования spark в качестве посредника.