.. czy jest coś oczywistego, co sugerowałoby, dlaczego moje zapytania mają średnio 500-650 ms?
Tak jest. Dzwonisz do mgo.Dial()
przed wykonaniem każdego zapytania. mgo.Dial()
musi za każdym razem łączyć się z serwerem MongoDB, który zamykasz zaraz po zapytaniu. Nawiązanie połączenia może z dużym prawdopodobieństwem zająć setki milisekund, w tym uwierzytelnianie, przydzielanie zasobów (zarówno po stronie serwera, jak i klienta) itp. To bardzo marnotrawstwo.
Ta metoda jest zwykle wywoływana tylko raz dla danego klastra. Kolejne sesje z tym samym klastrem są następnie ustanawiane przy użyciu metod New lub Copy w uzyskanej sesji. To sprawi, że będą współdzielić bazowy klaster i odpowiednio zarządzać pulą połączeń.
Utwórz globalną zmienną sesji, połącz się przy starcie raz (używając np. pakietu init()
funkcji) i użyj tej sesji (lub jej kopii / klonu, uzyskanej przez Session.Copy()
lub Session.Clone()
).Na przykład:
var session *mgo.Session
var info *db.Inf // Use your type here
func init() {
var err error
if info, err = db.Info(); err != nil {
log.Fatal(err)
}
if session, err = mgo.Dial(info.ConnectionString()); err != nil {
log.Fatal(err)
}
}
func (r userRepo) GetUserByID(id string) (User, error) {
sess := session.Clone()
defer sess.Close()
// Now we use sess to execute the query:
var user User
c := sess.DB(info.Db()).C("users")
// Rest of the method is unchanged...
}