Guram Savinov
Guram Savinov

Reputation: 689

Performance: get+[delete if exists] vs delete

I have a case with two options:

  1. check a tuple existense and delete if it exists
  2. unconditional delete

The majority of operations are trying to delete a tuple which is not exist in space (get without delete or uncoditional delete).

I wonder what is preferrable operation?

Upvotes: 3

Views: 115

Answers (1)

Dmitry Sharonov
Dmitry Sharonov

Reputation: 481

TL;DR: option 1 will be usually faster.

In general, DELETE operation is slower then get, since it's write operation. However, there are several moments that may change this on your particular workload:

  1. DELETE operation on a non-existent key will still generate a wal-entry, which will take most of it's time. So, if you use wal_mode='none', no-op DELETE will be much faster.
  2. GET operation will lead to msgpack decoding, so if your keys are relatively small, and tuples are relatively large, your GET operations will be slower.
  3. (Obviously) percentage of non-existent keys in your requests will affect speed ratio between two options significantly.

You may tune this short bench to see real numbers:

clock = require('clock')
box.cfg{}
t = box.schema.space.create('t', {if_not_exists=true})
t:create_index('pk', {if_not_exists=true})
t:truncate()
for i = 1,10000 do
    t:replace{i, 'abcdef'}
end

local keys = {}
for i=1,50000 do
    table.insert(keys, math.random(1, 50000))
end

tm = clock.time()
for _, key in ipairs(keys) do
    --if t:get(key) ~= nil then
        t:delete(key)
    --end
end
collectgarbage()
print(clock.time()-tm)

Here,

  • numbers are used in keys,
  • short strings are used as tuple payload,
  • and get-hit ratio is approximately 20%.

Uncomment the if-clause to measure option 1.

On my laptop and numbers above, this bench shows that option 1 is roughly 6 times faster.

Upvotes: 3

Related Questions