dbplyr 生成意外 SQL 查询
dbplyr generating unexpected SQL query
我正在使用 dbplyr
:
向 MySQL 数据库发送一个简单的查询
library(dbplyr)
my_conn<-dbConnect(...)
tab<-tbl(my_conn, "myTable")
tab %>% select(id, date, type) %>%
filter(type = 'foobar')
但是,如果我用 show_query()
检查生成的 SQL,我得到这个:
SELECT *
FROM (SELECT `id`, `date`, `type`
FROM `myTable`) `q01`
WHERE (`type` == 'foobar')
这个查询执行起来很慢。
如果我改为在服务器上执行以下 SQL 命令:
SELECT id, date, type FROM db.myTable WHERE type = 'foobar'
那么 return 几乎是瞬时的。
我的问题是:为什么 dbplyr
做 SELECT *
(即 select 全部) 然后 做嵌套 select 在第 2 行?另外,为什么“q01”出现在这个查询中?与直接在服务器上执行最小命令相比,这可能就是为什么我的查询 运行 非常慢的原因吗?随着操作复杂性的增加,我可能希望 dbplyr
创建低效的 SQL 查询,但是——至少在这种情况下——我真的无法编写更简洁的操作集。它只是一个 select 和过滤器(SELECT 和 WHERE)。
我想你想把它们串起来。执行 tab <- tbl(my_conn, "myTable")
后,您已经下载了整个 table。
tbl(my_conn, "myTable") %>%
select(id, date, type) %>%
filter(type = 'foobar')
dbplyr 正按我的预期生成 SQL 查询。它所做的是一个查询内嵌另一个查询:
SELECT id, date, type FROM myTable
是超查询中的子查询
SELECT *
FROM (
subquery
) q01
WHERE type = foobar
q01
是给子查询的名称。与 AS
关键字相同。例如:FROM very_long_table_name AS VLTN
.
是的,这个嵌套很丑。但是许多 SQL 引擎都有一个查询优化器,可以计算执行查询的最佳方式。在 SQL 服务器上,我注意到性能差异不大,因为查询优化器找到了一种比所写方式更快的执行方式。
但是,对于 MySQL,嵌套查询似乎会导致性能下降。参见 here, here, and here。
可能解决此问题的一件事是更改 R:
中 select
和 filter
命令的顺序
tab %>%
filter(type = 'foobar') %>%
select(id, date, type)
可能会生成翻译后的查询:
SELECT `id`, `date`, `type`
FROM `myTable`
WHERE (`type` == 'foobar')
哪个效果会更好。
我正在使用 dbplyr
:
library(dbplyr)
my_conn<-dbConnect(...)
tab<-tbl(my_conn, "myTable")
tab %>% select(id, date, type) %>%
filter(type = 'foobar')
但是,如果我用 show_query()
检查生成的 SQL,我得到这个:
SELECT *
FROM (SELECT `id`, `date`, `type`
FROM `myTable`) `q01`
WHERE (`type` == 'foobar')
这个查询执行起来很慢。
如果我改为在服务器上执行以下 SQL 命令:
SELECT id, date, type FROM db.myTable WHERE type = 'foobar'
那么 return 几乎是瞬时的。
我的问题是:为什么 dbplyr
做 SELECT *
(即 select 全部) 然后 做嵌套 select 在第 2 行?另外,为什么“q01”出现在这个查询中?与直接在服务器上执行最小命令相比,这可能就是为什么我的查询 运行 非常慢的原因吗?随着操作复杂性的增加,我可能希望 dbplyr
创建低效的 SQL 查询,但是——至少在这种情况下——我真的无法编写更简洁的操作集。它只是一个 select 和过滤器(SELECT 和 WHERE)。
我想你想把它们串起来。执行 tab <- tbl(my_conn, "myTable")
后,您已经下载了整个 table。
tbl(my_conn, "myTable") %>%
select(id, date, type) %>%
filter(type = 'foobar')
dbplyr 正按我的预期生成 SQL 查询。它所做的是一个查询内嵌另一个查询:
SELECT id, date, type FROM myTable
是超查询中的子查询
SELECT *
FROM (
subquery
) q01
WHERE type = foobar
q01
是给子查询的名称。与 AS
关键字相同。例如:FROM very_long_table_name AS VLTN
.
是的,这个嵌套很丑。但是许多 SQL 引擎都有一个查询优化器,可以计算执行查询的最佳方式。在 SQL 服务器上,我注意到性能差异不大,因为查询优化器找到了一种比所写方式更快的执行方式。
但是,对于 MySQL,嵌套查询似乎会导致性能下降。参见 here, here, and here。
可能解决此问题的一件事是更改 R:
中select
和 filter
命令的顺序
tab %>%
filter(type = 'foobar') %>%
select(id, date, type)
可能会生成翻译后的查询:
SELECT `id`, `date`, `type`
FROM `myTable`
WHERE (`type` == 'foobar')
哪个效果会更好。