Как я могу оптимизировать свой Google Script, чтобы быстрее получать данные SQL? - PullRequest
0 голосов
/ 12 марта 2019

Я довольно новичок в скриптах Google и пытаюсь как можно быстрее импортировать данные SQL в электронную таблицу Google.

Я использовал этот скрипт:

function readItems() {    
  var conn = Jdbc.getConnection("jdbc:sqlserver://server","UN","PW");
  var stmt = conn.createStatement();
  var rs = stmt.executeQuery("SELECT * FROM [dbo].[PriceList]WHERE [Product Line]<>'AL' AND [Product Line]<>'EL' AND [Product Line]<>'Accessories'ORDER BY [Product Line],Family,[Item Code]");

  var doc = SpreadsheetApp.getActive().getSheetByName('Data');
  var cell = doc.getRange('a1');
  var row = 0;
  while(rs.next()) {
    cell.offset(row, 0).setValue(rs.getString(1));
    cell.offset(row, 1).setValue(rs.getString(2));
    cell.offset(row, 2).setValue(rs.getString(3));
    cell.offset(row, 3).setValue(rs.getString(4));
    cell.offset(row, 4).setValue(rs.getString(5))
    row++;
  }
  rs.close();
  stmt.close();
  conn.close();
}

В примере для этого конкретного запроса он читает и записывает ~ 1200 строк и первоначально для завершения сценария требуется около 1,5 минут, но затем кажется, что существует какой-то тип кэша, поскольку для запроса после первоначального запроса требуется всего около 30 секунд запуск сценария.

Это приличное время выполнения, однако, когда я сравниваю это с подключением к данным в Excel, оно все равно значительно дольше.

Итак, я пытался с моими ограниченными знаниями, чтобы увидеть, смогу ли я сделать это быстрее.

После некоторого краткого поиска в Google я наткнулся на эту статью , в которой говорилось, что было бы более эффективно использовать массив для хранения данных.

Итак, с этим знанием и некоторым дополнительным поиском я наткнулся на этот сценарий:

var address = "server"; //ex. '10.1.1.1:1433'
var user = "UN";
var userPwd = "PW";
var db = "DB";

var dbUrl = 'jdbc:sqlserver://' + address + ';databaseName=' + db;   

function UpdatePriceList() {
  var conn = Jdbc.getConnection(dbUrl, user, userPwd); 
  var stmt = conn.createStatement();

  var results = stmt.executeQuery("SELECT * FROM [dbo].[PriceList]WHERE [Product Line]='AL' OR [Product Line]='EL'OR [Product Line]='Accessories'ORDER BY [Product Line],Family,[Item Code]");
  var metaData=results.getMetaData();
  var numCols = metaData.getColumnCount();

  var sheet = SpreadsheetApp.getActive().getSheetByName('Data');
  sheet.clearContents();

  var arr=[];  
  for (var col = 0; col < numCols; col++) {
    arr.push(metaData.getColumnName(col + 1));
  }   
  sheet.appendRow(arr);

  while (results.next()) {
    arr=[];   
    for (var col = 0; col < numCols; col++) {   
      arr.push(results.getString(col + 1));
    }
    sheet.appendRow(arr);   
  }

  results.close();
  stmt.close();
  conn.close();

  sheet.autoResizeColumns(1, numCols+1);   
}

К моему удивлению, тот же запрос с новым скриптом занимает 5-7 минут, и я не знаю, почему. Кажется также, что не происходит никакого кеширования, как это происходит с другим сценарием, так что для его завершения требуется примерно одинаковое количество времени, тогда как после первоначального запуска первого сценария наблюдается значительный выигрыш во времени.

Мне нравится более динамичный характер последнего, поскольку мне не нужно настраивать содержимое цикла на основе результатов запроса, поскольку я повторно использую сценарий, однако разница во времени выполнения убивает эту новизну.

Может ли кто-нибудь дать совет о том, как адаптировать динамическую природу последнего к первому, и / или предложить какой-либо совет о том, как улучшить этот скрипт для достижения более быстрого времени выполнения?

1 Ответ

1 голос
/ 12 марта 2019

Этот код считывает строку из объекта результатов один за другим и добавляет к листу.Замените это -

  while (results.next()) {
    arr=[];   
    for (var col = 0; col < numCols; col++) {   
      arr.push(results.getString(col + 1));
    }
    sheet.appendRow(arr);   
  }

на это -

var rows = [];
while (results.next()) {
    var arr=[];   
    for (var col = 0; col < numCols; col++) {   
      arr.push(results.getString(col + 1));
    }
    rows.push(arr);
}

sheet.getRange(2, 1, rows.length, numCols).setValues(rows);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...