Как преобразовать в кортежи и повысить производительность запросов SQL из 1 строки? - PullRequest
0 голосов
/ 16 октября 2019

Как это сделать?

  val (a,b) = spark.sql("SELECT 1,2").first

Примечания и мотивы

Мне нужно пересмотреть код, который имеет множество изолированных атрибутов из SQL, пример:

val today = spark.sql("SELECT date_format(now(),'yyyyMMdd')").as[String].first
val yesterday = spark.sql("SELECT date_format(date_add(now(),-1),'yyyyMMdd')").as[String].first
val xMax= spark.sql("SELECT max(x) FROM h_db.tt").as[String].first.toInt
val xMin= spark.sql("SELECT min(x) FROM h_db.tt").as[String].first.toInt

... И попробуйте что-то вроде

val (today,yesterday) = spark.sql("""
  SELECT date_format(now(),'yyyyMMdd'),  date_format(date_add(now(),-1),'yyyyMMdd')
""").as[(String,String)]
// error: constructor cannot be instantiated to expected type

val (xMax,xMIn) = spark.sql("SELECT max(x), min(x) FROM h_db.tt") // ... same problem

Команда SQL SELECT возвращает кортеж, поэтому теоретически кортежи являются естественным выбором, с минимальными приведениями и некоторой элегантностью синтаксиса. Как бы то ни было, основной мотивацией является производительность: сократить количество SQL-запросов SELECT.

1 Ответ

1 голос
/ 16 октября 2019

(это Вики, пожалуйста, уточните ответ с хорошим английским и более дидактическим объяснением)


На основе @ LuisMiguelMejíaSuárez,

Возможно сделать что-то как val (a,b) = spark.sql("SELECT 1,2").firstправильный синтаксис и синтаксис:

val (a,b) = spark.sql("SELECT 1,2").as[(Int, Int)].first

Пояснения

Возможен анализ типов данных с помощью Spark-shell Результаты и проверка схем:

  • Результат spark.sql("SELECT 1,2").first равен org.apache.spark.sql.Row, то есть Row.

  • Схема spark.sql("SELECT 1,2").first.schema, aStructType: org.apache.spark.sql.types.StructType = StructType(StructField(1,IntegerType,false), StructField(2,IntegerType,false))

, поэтому после проверенных типов данных вы можете решить, что делать, или понять свою реальную проблему приведения.

Помните, что Dataframeявляется набором данных [Строка], таким образом, .first является Строкой. Но вы всегда можете использовать Spark as[T], чтобы выполнить приведение от Роу к тому, что, как вы знаете, там есть (в данном случае кортеж), прежде чем запрашивать первое.

Другие любопытные вещи, (пожалуйста, отредактируйтеДидактическое объяснение здесь!):

  • Кастовать до или после .first? Почему?
  • В ролях toTypeX или as[TypeX]? Все таки?
  • Есть какие-то "неявные приведения"?
  • ...

Примеры из реальной жизни

Использование примеров вопроса и его улучшение:

val (isoToday,isoYesterday) = spark.sql("""
  SELECT date_format(now(),'yy-yy-MMdd'),  date_format(date_add(now(),-1),'yyyy-MM-dd')
""").as[(String,String)].first

val (today,yesterday) = spark.sql("""
  SELECT date_format(now(),'yyyyMMdd'),  date_format(date_add(now(),-1),'yyyyMMdd')
""").as[(String,String)].first  // as[(Int,Int)] not works...

val (intToday,intYesterday) = (today.toInt,yesterday.toInt) // no direct transform?

val (xMax,xMIn) = spark.sql("SELECT max(x), min(x) FROM h_db.tt").as[(Int,Int)].first  
   // direct to int, because SQL is typed
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...