Wykonuję wiele zapytań SQL do bazy danych o dużej sile przemysłowej, ale otrzymanie wyników zajmuje dużo czasu. Było znacznie szybciej, gdy mój komputer z R był prawie obok bazy danych, co prowadzi mnie do przekonania, że to opóźnienie między moim komputerem a bazą danych jest wąskim gardłem, a uruchamianie równoległych zapytań może przyspieszyć działanie. Jesteśmy na różnych kontynentach.Równoległa pętla for w systemie Windows
Oto wersja robocza, która nie jest równoległa:
doQueries <- function(filenameX, inp1, inp2) {
print(paste("Starting:", inp1, inp2, ",saving to", filenameX, sep=" "))
# Here should the query be (using RODBC)
# save(queryresults, file="filenameX")
}
input.rows <- cbind(c("file1.rda","file2.rda","file3.rda"),c("A","B","C"),c(12,13,14))
for (i in 1:nrow(input.rows)) {
doQueries(filenameX=input.rows[i,1], inp1=input.rows[i,2], inp2=input.rows[i,3])
}
próbowałem z następującego kodu, ale foreach Biblioteka wydają się nie być dostępna, a jak rozumiem od czytania na CRAN, parallel zastępuje wcześniejsze pakiety dla parallellingu ("pakiet" foreach "nie jest dostępny (dla R wersji 2.15.0)").
library(parallel)
library(foreach)
foreach (i=1:nrow(input.rows)) %dopar% {
doQueries(filenameX=input.rows[i,1], inp1=input.rows[i,2], inp2=input.rows[i,3])
}
Jak powinienem to zrobić?
Podziękowania dla wszystkich współpracowników za Stackoverflow!
/Chris
Aktualizacja: Dzięki nograpes, udało mi się załadować bibliotek. Poniższy kod wydaje się działać:
library(RODBC)
library(doParallel)
library(foreach)
# odbcCloseAll()
# my_conn <- odbcConnect("database", uid="xx", pwd="yy", case="nochange")
doQueries <- function(filenameX, inp1, inp2) {
print(paste("Starting:", inp1, inp2, ",saving to", filenameX, sep=" "))
# sql.test <- RODBC::sqlQuery(my_conn, "SELECT * FROM zzz LIMIT 100", rows_at_time=1024)
# save(sql.test, file="filenameX")
}
input.rows <- cbind(c("file1.rda","file2.rda","file3.rda"),c("A","B","C"),c(12,13,14))
cl <- makeCluster(3)
registerDoParallel(cl)
foreach (i=1:nrow(input.rows)) %dopar% {
doQueries(filenameX=input.rows[i,1], inp1=input.rows[i,2], inp2=input.rows[i,3])
}
stopCluster(cl)
Ale kiedy to rzeczywiste zapytania SQL, pojawia się ten błąd, komunikat: błąd w {: Zadanie 1 nie powiodło się - „pierwszy argument nie jest otwarty kanał RODBC”
Czy to możliwe, że koncepcyjnie nie zadziała? Że RODBC nie może obsłużyć więcej niż jednego zapytania naraz?
Naprawdę doceniam wsparcie.
/Chris
Aktualizacja 2: Dzięki a nograpes wiele dla bardzo dobrych i imponujących odpowiedzi. Trudno jest ocenić, czy same transfery danych są szybsze (myślę o około 20% szybszej całkowitej przepustowości), ale odkryłem, że ponieważ zapytania (około 100) mają różne czasy odpowiedzi i wymagają postprocessingu (który włączam do funkcji przed zapisaniem), uzyskuję lepsze wykorzystanie połączenia i lokalnego procesora. To znaczy. za pomocą tylko jednej kwerendy w tym czasie, procesory będą prawie nieużywane podczas przesyłania danych, a następnie łącze będzie ciche podczas pracy procesorów. W przypadku zapytań równoległych widzę dane przychodzące i procesory pracujące w tym samym czasie. W sumie stało się to znacznie szybciej. Wielkie dzięki!
/Chris
Jeśli wąskim gardłem jest połączenie sieciowe między komputerem a bazą danych, zapytanie równoległe nie będzie szybsze. Kwerendy SQL będą wykonywane jednocześnie w bazie danych (która może być trochę szybsza, ale może nie), a następnie przesłane do komputera. Wysłanie do twojej części komputera będzie powolną częścią, której wcale nie zmienisz przez zrównoleglenie jej. – nograpes