È possibile eseguire direttamente SQL per avere una singola query per entrambe le tabelle. Vi fornirò un esempio di query sterilizzata per tenere la gente spera di mettere le variabili direttamente nella stringa stessa (SQL iniezione pericolo), anche se questo esempio non ha specificato la necessità di esso:
@results = []
ActiveRecord::Base.connection.select_all(
ActiveRecord::Base.send(:sanitize_sql_array,
["... your SQL query goes here and ?, ?, ? are replaced...;", a, b, c])
).each do |record|
# instead of an array of hashes, you could put in a custom object with attributes
@results << {col_a_name: record["col_a_name"], col_b_name: record["col_b_name"], ...}
end
Edit: come ha detto Huy, un modo semplice è ActiveRecord::Base.connection.execute("...")
. Un altro modo è ActiveRecord::Base.connection.exec_query('...').rows
. Ed è possibile utilizzare istruzioni preparate native, ad es. se si utilizza Postgres, dichiarazione preparata può essere fatto con raw_connection, preparare e exec_prepared come descritto nel https://stackoverflow.com/a/13806512/178651
Si può anche mettere frammenti di SQL prime in ActiveRecord query relazionali: http://guides.rubyonrails.org/active_record_querying.html e nelle associazioni, oscilloscopi, ecc Si potrebbe probabilmente costruire lo stesso SQL con le query relazionali ActiveRecord e può fare cose interessanti con ARel come menziona Ernie in http://erniemiller.org/2010/03/28/advanced-activerecord-3-queries-with-arel/. E, naturalmente, ci sono altri ORM, gemme, ecc.
Se questo verrà utilizzato molto e l'aggiunta di indici non causerà altri problemi di prestazioni/risorse, si consideri l'aggiunta di un indice nel DB per payment_details.created_at e per payment_errors.created_at.
Se un sacco di dischi e non tutti i record devono presentarsi in una sola volta, considerare l'utilizzo di impaginazione:
Se avete bisogno di impaginare, considerare la creazione di una vista nel DB prima ha chiamato payment_records che combina le tabelle payment_details e payment_errors, quindi ha un modello per la vista (che sarà di sola lettura). Alcuni DB supportano visualizzazioni materializzate, che potrebbero essere una buona idea per le prestazioni.
Considerare anche le specifiche hardware o VM su server Rails e server DB, config, spazio su disco, velocità/latenza di rete/ecc., Prossimità, ecc. E prendere in considerazione l'inserimento di DB su diversi server/VM rispetto all'app Rails 't, ecc
Perché pensi che SQL raw sarà più veloce? Come sai che è un problema SQL? –
Senza vedere il piano di query, suppongo che il problema che stai riscontrando sia l'ordine di created_at. Probabilmente stai facendo una scansione seq su tutti questi tavoli interi (oh e inserendo anche la tabella del progetto). Effettuando due di questi in un unico metodo di controllo su un grande tavolo e DB sottodimensionato (i database di heroku sono ottimizzati in modo generico e relativamente sottodimensionati per i $$ spesi) è probabile che si verifichino timeout. Se non stai facendo molti inserti in queste tabelle potresti fare un indice ordinato: https://devcenter.heroku.com/articles/postgresql-indexes#sorted-indexes –
Beh, sarebbe sempre più veloce tagliare a mano il sql (se sai cosa stai facendo). Rails rende alcuni sql davvero sgradevoli. Funziona bene, ma per essere generale deve ... essere generale. Detto questo, Jim probabilmente ha ragione ... la creazione dell'indicizzazione sarebbe stata migliore. Prova a eseguire la query in pgadmin (contro il tuo db) – baash05