New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compound Secondary Index Speed #1526
Comments
I'm sort of at a loss on this one. I did some cursory profiling work with perf top and nothing lit up. @danielmewes is going to do some more in depth profiling. |
@linuxdynasty -- approximately how much data is in the DB? This might have to do with disk access rather than CPU. Also, if you run the queries twice (i.e. run query A, then query B, then query A, then query B), what does the performance look like? It might be that query A warms up the cache so it takes longer, and then query B operates entirely in RAM. What happens if you run them twice (A, B, A, B) or reverse the order (B, A)? |
@coffeemug Both @jdoliner and me could reproduce this on the data that @linuxdynasty provided to us. It doesn't seem to be an issue of the cache warming up, and the performance difference is consistent regardless the order. Current status: Somehow the profiler has stopped doing its job since I've last used it a week ago. I'm trying to get it working again... |
Preliminary results after profiling: In the first query, we seem to spend significant time on constructing in-memory secondary index data structures over and over. More specifically, the Apart from an analogon to It seems that the problem here is that we call the operator over and over for each document that we want to join. We should change the code to keep the in-memory structures around instead of deserializing them over and over again for each single document in the eq_join. |
Interesting, the optimization you suggest is definitely a good one and would fix this problem. How much more time is spent in the deserializing functions in the slow case? It seems weird to me that a slightly more complicated function has any reasonable difference. Also why on earth is the destructor that much more complicated? |
I'm not sure if I was clear in my description. The PS: So to answer your question: This deserialization does not happen at all in the fast case. |
Deserializing and compiling ReQL functions is expensive. We could probably make it better, but I think for most queries you only have to do it a small number of times. If we're currently compiling one function per row, we should almost certainly change that. |
If somebody wants to take a closer look: |
@jdoliner: A general question: When we do a get_all on a secondary index, do we have to go to all hash shards? Just wondering if that might also contribute to variant 1's relative slowness. |
@danielmewes yes. that's a good point actually. |
Actually, another thought: if we made |
@mlucy -- why would |
@mlucy: Funny, I just had the same thought. :-) |
@coffeemug -- |
Ah, I see. |
We should also do batching for the other joins at the same time. |
Wait, that made no sense at all. Ignore me. |
... isn't |
Apparently I'm just grossly misinformed. |
@danielmewes, could I take this one? |
@mlucy sure, go ahead! |
@coffeemug -- the goal is to send batches, not for parallelism but to avoid incurring per-query overhead (like compiling secondary index functions) for every row. |
So, I'm not sure that batches work well here. We use range gets for |
The workaround involving batches would require some thought, and might just end up being terrible. If anyone else wants to take this before I get to it, feel free. |
Actually, I just had another thought: if we made it so that we only load and compile the function the first time we see a truncated key, then the vast majority of these queries would never need to do it. (We only need the function to disambiguate truncated keys.) |
I guess that might be a very easy change which would solve about half of the problem. Note that |
(actually not sure about it being a "very easy" change, ignore that. I have no clue how difficult or easy it would actually be) |
hi |
Working on this. |
An optimization for caching secondary index functions is in CR 3171. |
After taking a brief look, I think I might need @mlucy's help on this one... |
Assigning @mlucy for the multi-key |
I'll be taking over the multi-key |
The |
(It turned out that what we were doing in @VeXocide's branch wasn't actually sufficient for a few edge cases (truncated keys and multiple copies of the same datum in the |
It turns out this was branched off of |
This is in next and 2.1.x, will ship with RethinkDB 2.1.5. |
I noticed when I was testing the speed of the queries that I have in my product, there was a significant decreases in certain queries that involved Compound Indexes.
For instance this query took Total time: 0:00:03.790848
eq_join with a compound index without a filter and using distinct()
Now this query is eq_join with an index with a filter took Total time: 0:00:01.156872
@jdoliner Can add more details to this, since he was working with me on this issue.
I expected the compound index to be faster than the filter when it came to the eq_join, but not in this case.
The text was updated successfully, but these errors were encountered: