Mam sześć zapytań SQL, które piszę R, z których każda zajmuje bardzo dużo czasu (~ 30 minut każda). Po każdym zwróceniu zapytania manipuluję danymi w przypadku niektórych standardowych raportów.Paralelizacja zapytań SQL w R
Co chciałbym zrobić, to używać maszyny wielordzeniowe, aby uruchomić te żądania SQL równolegle z R.
jestem na komputerze z systemem Windows z Oracle DB. Śledziłem numer blog post, aby użyć instrukcji doSNOW i foreach, aby spróbować podzielić te żądania i jest to najlepsza rzecz, jaką mogę znaleźć na stronie stackoverflow.
Udało mi się przekonwertować proces na wersję niepowiązaną% do% foreach, ale nie na% dopar%. Z% dopar% po prostu zwraca pusty zestaw. Poniżej znajduje się kod, który konfiguruje tabele i uruchamia kwerendy, dzięki czemu można zobaczyć, co się dzieje. Z góry przepraszam, jeśli jest za dużo podstawowego kodu.
Sprawdziłem niektóre z innych pakietów R, ale nie widziałem oczywistego rozwiązania. Także, jeśli masz lepszy sposób zarządzania tego rodzaju procesem, byłbym zainteresowany usłyszeniem go - pamiętaj, że jestem analitykiem, a nie naukowcem komputerowym. Dzięki!
#Creating a cluster
library(doSNOW)
cl <- makeCluster(c("localhost","localhost"), type = "SOCK")
registerDoSNOW(cl)
#Connecting to database through RODBC
ch=odbcConnect("",pwd = "xxxxx", believeNRows=FALSE)
#Test connection
odbcGetInfo(ch)
#Creating database tables for example purposes
qryA1 <- "create table temptable(test int)"
qryA2 <- "insert into temptable(test) values((1))"
qryA3 <- "select * from temptable"
qryA4 <- "drop table temptable"
qryB1 <- "create table temptable2(test int)"
qryB2 <- "insert into temptable2(test) values((2))"
qryB3 <- "select * from temptable2"
qryB4 <- "drop table temptable2"
sqlQuery(ch, qryA1)
sqlQuery(ch, qryA2)
doesItWork <- sqlQuery(ch, qryA3)
doesItWork
sqlQuery(ch, qryB1)
sqlQuery(ch, qryB2)
doesItWork <- sqlQuery(ch, qryB3)
doesItWork
result = c()
output = c()
databases <- list('temptable','temptable2')
#Non-parallel version of foreach
system.time(
foreach(i = 1:2)%do%{
result<-sqlQuery(ch,paste('SELECT * FROM ',databases[i]))
output[i] = result
}
)
output
#Parallel version of foreach
outputPar = c()
system.time(
foreach(i = 1:2)%dopar%{
#Connecting to database through RODBC
ch=odbcConnect(dsn ,pwd = "xxxxxx", believeNRows=FALSE)
#Test connection
odbcGetInfo(ch)
result<-sqlQuery(ch,paste('SELECT * FROM ',databases[i]))
outputPar[i] = result
}
)
outputPar
sqlQuery(ch, qryA4)
sqlQuery(ch, qryB4)
wysyłania zapytania do bazy danych w układzie równoległym tylko, aby proces wolniej, zależnie od tego, co jest przyczyną butelki. Czy jesteś pewien, że wąskim gardłem jest instancja R działająca na twoim komputerze (nie baza danych, połączenie sieciowe, komputer, na którym działa baza danych itp.)? –
Czy pakiet "RODBC' jest załadowany do węzłów klastra? Jeśli nie, dodaj '.packages =" RODBC "' do swojego wywołania 'foreach()'. – BenBarnes
@Joshua Ulrich - Baza danych jest dość solidna, ponieważ jest komercyjną instalacją Oracle. Kwerendy po prostu łączą się z kilkoma tabelami wymagającymi dużego przetwarzania w bazie danych. Ręczny sposób, który przyspieszyłbym, to zainicjowanie kilku wystąpień od programisty SQL, ale skrypt R wykonuje dla mnie wiele przetwarzania zapytań, więc wolałbym, aby R inicjował wiele zapytań naraz, tak aby najdłużej trzeba czekać, to długi czas zapytania zamiast dodawania wszystkich czasów zapytania razem. –