如何创建非聚集索引以从 R 中的 SQLite DB 查询和收集数据以进行绘图?

How to create non-clustered indexes for querying and collecting data from an SQLite DB in R for plotting?

我有一个 .csv 文件,其中包含 105M 行和 30 列,我想查询它以在 R shiny 应用程序中进行绘图。

它包含看起来像这样的字母数字数据:

        #Example data
        df<-as.data.frame(percent=as.numeric(rep(c("50","80"),each=5e2)),
                          maskProportion=as.numeric(rep(c("50","80")),each=5e2),
                          dose=runif(1e3),
                          origin=as.factor(rep(c("ABC","DEF"),each=5e2)),
                          destination=as.factor(rep(c("XYZ","GHI"),each=5e2))
                          )

write.csv(df,"PassengerData.csv")

在终端中,我已将其提取到 SQLite 数据库中,如下所示:

$ sqlite3 -csv PassengerData.sqlite3 '.import PassengerData.csv df'

来自:

到目前为止一切顺利。

我遇到的问题是在 R 中查询的速度,所以我尝试在终端中重新索引数据库。

sqlite3 中,我尝试在 link https://data.library.virginia.edu/creating-a-sqlite-database-for-use-with-r/ :

之后创建百分比、maskProportion、起点和终点的索引
$ sqlite3 create index "percent" on PassengerData("percent");
$ sqlite3 create index "origin" on PassengerData("origin");
$ sqlite3 create index "destination" on PassengerData("destination");
$ sqlite3 create index "maskProp" on PassengerData("maskProp");

我 运行 磁盘空间不足 space 因为每次我创建索引时我的数据库似乎都在变大。例如。在 运行ning 第一个命令之后,大小为 20GB。我怎样才能避免这种情况?

我假设担心的是 运行 collect() 将数据从 SQL 传输到 R 对您的应用来说太慢了。目前尚不清楚在传递给 R.

之前,您如何/是否在处理 SQL 中的数据

需要考虑的几件事:

  • 索引不会从 SQL 复制到 R。SQL 使用磁盘外的数据,因此知道在哪里查找数据的特定部分可以节省时间。 R 处理内存中的数据,因此不需要索引。
  • collect 将数据从远程 table(在本例中为 SQLite)传输到 R 内存中。如果您的目标是将数据传输到 R,您可以将 csv 直接读入 R,而不是将其写入 SQL,然后从 SQL 读入 R.
  • SQL 是进行数据处理/准备大型数据集的更好选择,而 R 是详细分析和可视化的更好选择。但是,如果 R 和 SQL 在同一台机器上都是 运行,那么两者都会受到 cpu 速度的限制。不用担心 SQL 和 R 在单独的硬件上 运行。

您可以采取一些措施来提高性能:

(1)只将SQL中需要的数据读入R。先准备好SQL中的数据。例如,对比以下内容:

# collect last
local_r_df = remote_sql_df %>%
  group_by(origin) %>%
  summarise(number = n()) %>%
  collect()

# collect first
local_r_df = remote_sql_df %>%
  collect() %>%
  group_by(origin) %>%
  summarise(number = n())

这两个将产生相同的输出。但是,在第一个示例中,摘要发生在 SQL 中,并且只有最终结果被复制到 R;而在第二个示例中,整个 table 被复制到 R,然后在其中进行汇总。 Collect last 可能比 collect first 具有更好的性能,因为它仅在 SQL 和 R.

之间传输少量数据

(2) 为您的应用预处理数据。 如果您的应用仅检查来自有限几个方向的数据,则可以对数据进行预处理/预汇总.

例如,假设用户最多可以选择两个维度并接收一个交叉表,那么您可以计算所有双向交叉表并保存它们。这可能比整个数据库小得多。然后在运行时,您的应用加载准备好的摘要并向用户显示他们请求的任何摘要。这可能会快得多。