- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要每天多次将几千行推送到 Redshift 中。但出于管理原因,我不能使用 S3 中的批量插入。最快的方法是什么?
有 3 种方法(我可以看到)将行从 R 插入到 Amazon Redshift 中的表中:
INSERT VALUES
查询上述每种方法都比之前的方法快一个数量级。我喜欢使用批量插入来创建或更新表,但我们的组织已做出安全和管理决定,不允许业务用户将数据批量加载或卸载到 S3。所以这让我无法使用包 redshiftTools上传文件。
我可以使用 RODBC::sqlSave
执行上面的第 1 条。这很慢,但最终完成了工作。
我宁愿拥有类似 sqlSave
的东西,它可以一次插入多行数据。但不要超过 Redshift 的行/大小限制。这对于简单的数据结构来说很容易,但是处理整数、字符、日期等的通用函数将是理想的,因为我不会只对一个表执行此操作。因此,我打开了 sqlSave
的源代码,并开始推出我自己的函数来构建多行插入,将数据分成 1000 行 block ,并为每个 block 构建和执行查询。
但是我在这里停下来问这是否已经完成了?有没有更好的办法?我有这种感觉,也许 R 的其他 SQL 包之一具有执行类似操作的功能。然而,当我搜索时,我发现的都是其他人 having the same sort of problem .
有什么建议吗?
多亏了一些提示,我研究了 RODBC::sqlSave
中的 fast=TRUE
开关。文档听起来像是我所追求的:
fast: logical. If false, write data a row at a time. If true, use a parametrized INSERT INTO or UPDATE query to write all the data in one operation.
所以我想我应该对此进行测试。所以我创建了一个包含 10 条记录和 2 列的小数据框:
df <- data.frame(a=rnorm(10), b=sample(letters, 10, replace=TRUE),
stringsAsFactors = FALSE)
然后我使用 benchmark
来计算 5 次复制的执行时间:
benchmark( sqlSave(dbhandle, df, tablename = 'jal_test1', append=TRUE, fast=TRUE), replications = 5)
# test replications elapsed relative user.self sys.self user.child sys.child
# 1 sqlSave(dbhandle, df, tablename = "jal_test1", append = TRUE, fast = TRUE) 5 512.59 1 0.08 0.03 NA NA
benchmark( sqlSave(dbhandle, df, tablename = 'jal_test1', append=TRUE, fast=FALSE), replications = 5)
# test replications elapsed relative user.self sys.self user.child sys.child
# 1 sqlSave(dbhandle, df, tablename = "jal_test1", append = TRUE, fast = FALSE) 5 264.37 1 0.08 0.02 NA NA
这有点难读,但总而言之:
fast=TRUE
耗时 512 秒fast=FALSE
耗时 264 秒有25条记录,时间上升到:
fast=TRUE
耗时 1208 秒fast=FALSE
耗时 604 秒这对我来说完全没有意义。
我尝试了 test=TRUE
开关,认为它会告诉我发生了什么,但我根本不知道它做了什么......但是转向 verbose=TRUE
帮助我意识到 fast=TRUE
并不像我想的那样。它似乎使用了替换,但没有做一个大的插入。它仍然执行 nrow(df)
的插入操作:
> df <- data.frame(a=rnorm(5), b=sample(letters, 5, replace=TRUE), stringsAsFactors = FALSE)
> sqlSave(dbhandle, df, tablename = 'jal_test1', append=TRUE, fast=FALSE, verbose=TRUE)
Query: INSERT INTO "jal_test1" ( "rownames", "a", "b" ) VALUES ( '1', -1.45261402, 'd' )
Query: INSERT INTO "jal_test1" ( "rownames", "a", "b" ) VALUES ( '2', -0.01642518, 'm' )
Query: INSERT INTO "jal_test1" ( "rownames", "a", "b" ) VALUES ( '3', 1.11767938, 'm' )
Query: INSERT INTO "jal_test1" ( "rownames", "a", "b" ) VALUES ( '4', -0.63480166, 'a' )
Query: INSERT INTO "jal_test1" ( "rownames", "a", "b" ) VALUES ( '5', -0.75538702, 'k' )
> sqlSave(dbhandle, df, tablename = 'jal_test1', append=TRUE, fast=TRUE, verbose=TRUE)
Query: INSERT INTO "jal_test1" ( "rownames", "a", "b" ) VALUES ( ?,?,? )
Binding: 'rownames' DataType -9, ColSize 255
Binding: 'a' DataType 6, ColSize 17
Binding: 'b' DataType -9, ColSize 255
Parameters:
no: 1: rownames 1/***/no: 2: a -1.45261/***/no: 3: b d/***/
no: 1: rownames 2/***/no: 2: a -0.0164252/***/no: 3: b m/***/
no: 1: rownames 3/***/no: 2: a 1.11768/***/no: 3: b m/***/
no: 1: rownames 4/***/no: 2: a -0.634802/***/no: 3: b a/***/
no: 1: rownames 5/***/no: 2: a -0.755387/***/no: 3: b k/***/
最佳答案
我最终无法找到可以在 R 中进行分块的 SQL 写入函数的实现。但我确实看到在 Python 中,sqlalchemy
包与 pandas
组合在一起可以轻松做到这一点。因此,我推出了 Reticulate 并将 Python 包装在一些 R 代码中,以创建一个函数来写入 redshift。看起来有点矫枉过正,但无需我重新实现任何东西就可以完成工作:
start_python <- function(){
library(reticulate)
use_condaenv( "r-reticulate")
pd <- import('pandas')
sa <- import('sqlalchemy')
}
# write a table to RDW sandbox
write_to_redshift <- function(df, tablename, if_exists = 'append'){
pd_df <- r_to_py(df)
eng = sa$create_engine('postgres://user:pwd@redshift_name:5439/db_name')
conn = eng$connect()
write_result <- pd_df$to_sql( name=tablename, con=conn, index = FALSE, if_exists = if_exists, schema='my_schema', chunksize=10000L)
conn$close()
return(write_result)
}
关于sql - 使用 R 一次将多条记录插入 Redshift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50646042/
我们可以直接将一张表从一个 Redshift 集群复制到另一个 Redshift 集群吗? 我知道可以使用 s3 作为临时存储来实现表复制(即从第一个集群卸载到 s3,然后从 s3 复制到另一个集群)
我在 AWS Redshift 集群中执行了以下操作以从 S3 读取 Parquet 文件。 create external schema s3_external_schema from data c
我在 AWS Redshift 集群中执行了以下操作以从 S3 读取 Parquet 文件。 create external schema s3_external_schema from data c
在 Amazon Redshift 中创建数据表时,您可以指定各种 encodings,例如 MOSTLY32 或 BYTEDICT 或 LZO。这些是在磁盘上存储列值时使用的压缩。 我想知道我选择的
我在 s3 中有一个压缩文件。我想将它插入到 RedShift 数据库中。我的研究发现做到这一点的唯一方法是启动一个 ec2 实例。将文件移到那里,解压缩,然后将其发送回 S3。然后将其插入到我的 R
为了在 Multi-Tenancy 维度 DW 中处理特定对象的自定义字段,我创建了 Redshift 不太喜欢的超宽非规范化维度表(数百列,列的硬编码限制);)。 user1|attr1|attr2
Redshift 文档将时间序列表确定为最佳实践: http://docs.aws.amazon.com/redshift/latest/dg/c_best-practices-time-series
我正在使用 redshift 的 COPY 命令从 S3 复制 json 数据。 表定义如下: CREATE TABLE my_raw ( id BIGINT IDENTITY(1,1), ... .
如何获取导出的键(数据库元数据)。即使 redshift 不支持外键和主键,我也可以在系统表中看到它们。这里的问题是在系统表中,外键的多列作为数组存在于一列中(尽管redshift不支持数组)。是否可
我正在寻找一种创建 Redshift 查询的方法,该查询将从每天生成的表中检索数据。我们集群中的表具有以下形式: event_table_2016_06_14 event_table_2016_06_
在 Redshift 中,当我们将结果导入 TABLEAU 时,我们试图为从查询返回的列提供更有意义的别名,问题是 RedShift 将所有字母转换为小写字母,即从“事件日期” ” 然后它返回“事件日
据我了解,Redshift 是为性能而不是可用性而构建的。文档 https://aws.amazon.com/redshift/faqs/建议一旦任何一个节点宕机,整个集群都会宕机,直到该节点恢复。在
我试图找出与中止查询相关的原因/错误,其中可以从 STL_query 表中找到中止的查询。我为此使用了 STL_errors,但发现错误上下文与 process id 相关,而不是特定的查询 id。有
我们正在使用 AWS Redshift DB 并希望创建一个在线复制(这样也可以完全更新更改)? 原因是我们希望为我们的一个部门提供一个单独的环境来运行他们自己的查询,因为他们可能会“发疯”并做一些
我在使用 DataGrip 的 Redshift 集群上运行查询需要超过 10 个小时才能运行,不幸的是,这些查询经常失败。唉,DataGrip 与数据库的连接保持的时间不够长,我无法看到查询失败的错
我正在对 redshift 中的一些查询进行基准测试,以便我可以对我对表所做的更改进行一些智能说明,例如添加编码和运行 vacuum。我可以查询stl_query带有 LIKE 子句的表来查找我感兴趣
删除表后,redshift 是否回收可用磁盘空间,或者我们是否需要运行 vaccum。 最佳答案 drop table 释放空间。 如果您正在对表的行进行删除操作,那么您应该触发 vaccumm de
有没有办法在 Amazon Redshift 中计算具有固定窗口大小的加权移动平均值?更详细地说,给定一个带有日期列和值列的表,对于每个日期计算指定大小窗口的加权平均值,并在辅助表中指定权重。 到目前
我注意到第一次在 RedShift 上运行查询需要 3-10 秒。当我再次运行相同的查询时,即使在 WHERE 条件中使用不同的参数,它也会运行得很快(0.2 秒)。 我正在谈论的查询在一个约 1M
我明白 the COPY command非常有效地导入大量数据。但是使用 the INSERT command 将数据从一个表复制到另一个表是慢的。有没有更有效的方法将数据从一个表复制到另一个表?或者
我是一名优秀的程序员,十分优秀!