opened
lucatorella
username_0
I'm trying to update couchbase from version 1.1.1 to version 1.2.2.

What I've noticed is that if I run a query just after the synchronization is done, it takes about 15-20 secs (I've about 10k documents in the database). Next queries takes 1 sec or less.

I'm not able to notice any difference when I'm using couchbase lite 1.1.1.

--------
* Version:   1.2.2
* Client OS: iOS 9.3.2
* Server:    couchdb 1.6.1
First query after synchronization takes a long time
issue
created
lucatorella
username_0
To be clearer, I subscribe to both `kCBLReplicationChangeNotification` and `kCBLReplicationChangeNotification`. 

Then when both `CBLReplicationStatus` are `Idle`, I create a query and run it.
comment
created
snej
username_1
The first query will update the index, so it'll be slower. (Indexes are updated lazily.) 2ms/doc seems a little slow, though; is your map block doing anything expensive?

Not sure what this has to do with updating to 1.2.2; are you saying that this behavior is worse in the new version?
comment
created
lucatorella
username_0
In my map block I'm just emitting all the keys. The code looks something like:
```
        for def in indexDefs {
            let view = database.viewNamed("localviews/\(def.name)")
            view.setMapBlock({ (doc, emit) in
                let keys = emitKeys(doc, fields: def.fields)
                if let keys = keys {
                    emit(keys, nil)
                }
                }, version: "1")
```

Yes, in version 1.1.1 I didn't notice this long delay. 

I haven't tried 1.2, or 1.2.1 because of other replication issues.
comment
created
snej
username_1
It would be great if you could use Instruments' time profiler to analyze where the time is being spent during that query.

A couple of ideas to improve performance:

1. The expression `def.fields` is being evaluated for every document indexed. Instead, you can evaluate it outside the `setMapBlock` call and use the value in the block.
2. Since all your view names start with `localviews/`, they're all in a group so their indexes will all be updated together whenever any of them is queried. This can save time if you need to query all the views at about the same time, but if you only need one of them, it's slower than just indexing that one view. You can give the views different name prefixes to group them differently.

None of this would have changed between 1.1 and 1.2, though...
comment
created
lucatorella
username_0
thank you for the useful tips. So profiling the app I discovered that the indexing takes about the same (I think I got confused because in version 1.1.1 `changesCount` is not really working, while in 1.2.2 it works better), but it's the replication as whole which is slower.

You can see it from this two screenshot where I'm doing an initial replication + query with the two versions of couchbase:

![screen shot 2016-06-08 at 10 18 29](https://cloud.githubusercontent.com/assets/1781236/15887564/3aa41ce6-2d63-11e6-9016-5e8d90f6824a.png)

![screen shot 2016-06-08 at 10 20 00](https://cloud.githubusercontent.com/assets/1781236/15887573/439278fc-2d63-11e6-998c-56de78152a8d.png)
comment
created
lucatorella
username_0
Quick update: 
So I'm listening to `kCBLReplicationChangeNotification` to get replication status:
With couchbase lite 1.1.1, I get a notification when the progress is "9674/9722" then there is a long wait and then I get the next notification that the replication is done. So I guess also indexing is completed and that's why there was this longer wait.

In version 1.2.2 it progress smoothly to "9722/9722". So when I get that the status has changed to .Idle actually Indexing is still needed.

Anyway, I can work around this change. I just wanted to let you know the different behavior.
comment
closed
snej
username_1
issue
created
snej
username_1
Async queries (including indexing) run on the same thread as the replicator, so if your app triggers such a query shortly before the replicator finishes, it's sort of a race whether the query or the replication will complete first. It might be a LiveQuery triggering the async query, if you've got one of those running.
comment
created
lucatorella
username_0
Is there a way to know when couchbase lite finished building indexes? Some kind of notification maybe?
comment
created
snej
username_1
No. If you want control over updating a view index you can run a (regular, non-async) query that will return minimal results, e.g. set limit=1. In 1.3 we're adding an `-updateIndex` method to CBLView that will just update the index without a query, and that has an async form as well that will notify you when the indexing is complete.
comment
created
lucatorella
username_0
Great, thanks!
comment