为什么RethinkDB非常慢?

I am getting started with RethinkDB, I have never used it before. I give it a try together with Gorethink following this tutorial.

To sum up this tutorial, there are two programs:

The first one updates entries infinitely.

for {
    var scoreentry ScoreEntry
    pl := rand.Intn(1000)
    sc := rand.Intn(6) - 2
    res, err := r.Table("scores").Get(strconv.Itoa(pl)).Run(session)
    if err != nil {
        log.Fatal(err)
    }

    err = res.One(&scoreentry)
    scoreentry.Score = scoreentry.Score + sc
    _, err = r.Table("scores").Update(scoreentry).RunWrite(session)
}

And the second one, receives this changes and logs them.

res, err := r.Table("scores").Changes().Run(session)

var value interface{}

if err != nil {
    log.Fatalln(err)
}
for res.Next(&value) {
    fmt.Println(value)
}

In the statistics that RethinkDB shows, I can see that there are 1.5K reads and writes per second. But in the console of the second program, I see 1 or 2 changes per second approximately.

Why does this occur? Am I missing something?

Im not sure why it is quite that slow, it could be because by default each query blocks until the write has been completely flushed. I would first add some kind of instrumentation to see which operation is being so slow. There are also a couple of ways that you can improve the performance:

  1. Set the Durability of the write using UpdateOpts

    _, err = r.Table("scores").Update(scoreentry, r.UpdateOpts{
        Durability: "soft",
    }).RunWrite(session)
    
  2. Execute each query in a goroutine to allow your code to execute multiple queries in parallel (you may need to use a pool of goroutines instead but this code is just a simplified example)

    for {
        go func() {
            var scoreentry ScoreEntry
            pl := rand.Intn(1000)
            sc := rand.Intn(6) - 2
            res, err := r.Table("scores").Get(strconv.Itoa(pl)).Run(session)
            if err != nil {
                log.Fatal(err)
            }
    
            err = res.One(&scoreentry)
            scoreentry.Score = scoreentry.Score + sc
            _, err = r.Table("scores").Update(scoreentry).RunWrite(session)
        }()
    }
    

This code:

r.Table("scores").Update(scoreentry).RunWrite(session)

Probably doesn't do what you think it does. This attempts to update every document in the table by merging scoreentry into it. This is why the RethinkDB console is showing so many writes per second: every time you run that query it's resulting in thousands of writes.

Usually you want to update documents inside of ReQL, like so:

r.Table('scores').Get(strconv.Itoa(pl)).Update(func (row Term) interface{} {
  return map[string]interface{}{"Score": row.GetField('Score').Add(sc)};
})

If you need to do the update in Go code, though, you can replace just that one document like so:

r.Table('scores').Get(strconv.Itoa(pl)).Replace(scoreentry)