如何优化我的 Google 脚本以更快地检索 SQL 数据?
Posted
技术标签:
【中文标题】如何优化我的 Google 脚本以更快地检索 SQL 数据?【英文标题】:How can I optimize my Google Script to retrieve SQL data quicker? 【发布时间】:2019-03-12 18:00:44 【问题描述】:我对谷歌脚本相当陌生,我正在尝试尽快将 SQL 数据导入谷歌电子表格。
我一直在使用这个脚本:
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 中的数据进行比较时,它仍然相当长。
所以我一直在尝试用我有限的知识来看看我是否可以让它更快。
经过一些简短的谷歌搜索后,我发现this 文章表明使用数组来保存数据会更有效。
因此,凭借这些知识和一些额外的谷歌搜索,我发现了这个脚本:
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 分钟才能完成,我不知道为什么。似乎也没有像使用其他脚本那样进行任何缓存,因此它始终需要大约相同的时间才能完成,而在使用前者初始运行之后,时间上却有相当大的增益。
我喜欢后者更具动态性,因为我不必根据查询结果调整循环内容,因为我重用了脚本,但是运行时的差异扼杀了这种新颖性。
任何人都可以就如何使后者的动态特性适应前者和/或就如何改进此脚本以实现更快的运行时提供任何建议吗?
【问题讨论】:
考虑使用getRange(..).setValues
而不是appendRow
。第一个脚本没有调用原子操作,setValues
也不是原子的。
创建一个值数组,然后在一个操作中将它们插入到一个范围内,比一个接一个地插入许多单行要快。
@ra89fi 谢谢你的回复,我也是这么想的,但是我对如何执行这个概念有点缺乏经验,你能举个例子吗?
@aaron ***.com/help/someone-answers
【参考方案1】:
此代码从结果对象中逐一读取一行并附加到工作表中。替换这个 -
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);
【讨论】:
完美!这就是我一直在寻找的。span> 现在在sheet中写入数据需要多长时间? 现在时钟在 ~15-20 秒,我再高兴不过了。再次感谢!以上是关于如何优化我的 Google 脚本以更快地检索 SQL 数据?的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中,如何在继续编写代码之前安全地确保从 Google 检索数据(日期和时间)?