Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
vinyl: optimize select in case secondary key is updated frequently
If a space has secondary keys, an update operation generates a REPLACE in the primary key and a DELETE + REPLACE in each secondary key. We don't need a DELETE in the primary key, because a field indexed by the primary key cannot be updated so a REPLACE is enough to update the tuple stored in the index. On the contrary, a field indexed by a secondary key can be updated so we need a DELETE to remove the old tuple from the index. As a result, if a field indexed by a secondary key gets updated often (e.g. the user frequently calls space:update({x}, {{'+', 2, 1}}) on a space with a secondary index over field #2), a lot of DELETE statements will be generated. The DELETE statements won't be compacted until major compaction so a range select over a secondary index may take long, because it will have to iterate over all those useless DELETEs. In fact, the REPLACE generated by an update operation can be safely substituted with an INSERT in a secondary index. INSERT + DELETE are annihilated on dump/compaction so that would solve the problem. Unfortunately, we can't substitute REPLACE with INSERT immediately on update, because statements are shared between primary and secondary indexes in memory and we can't use an INSERT in a primary index in case of update (see above). However, it is OK to turn REPLACE generated by an update in a secondary key to an INSERT on dump/compaction. We just need a way to identify such REPLACE statements somehow. In contrast to normal REPLACEs, a REPLACE statement generated by an update operation usually has a column mask. There's only one exception: if an update operation updates all secondary keys, the column mask isn't stored (vy_stmt_column_mask() returns UINT64_MAX). This is done for the sake of memory usage minimization, but it doesn't seem to make much sense: first, updates that touch all secondary indexes should be rare; second, we save only 8 bytes per statement. Let's remove this optimization and store column mask in REPLACE statements generated by update operations unconditionally and use this information in the write iterator to turn REPLACEs into INSERTs. See #2875
- Loading branch information
Showing
4 changed files
with
57 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters