mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-01-27 07:48:16 -05:00
tdb_sql/Thing: Assume data props should be INSERTed on thing creation.
Previously, setting data props on a thing would result in a SELECT to determine which data properties already existed, and then a sequence of INSERTs and UPDATEs (with some batching) to get the database in the right state. The account master wasn't too happy with those extra selects, so we made it so that the app would optimistically UPDATE and if no rows were changed do INSERTs instead (with appropriate batching as above). Unfortunately, this greatly increases the number of operations done when adding new data props, such as at thing creation time, and on some tables that's almost entirely all of the workload. This patch takes advantage of the fact that we know no data attributes will exist at thing creation time and therefore we can blindly INSERT without doing UPDATEs or SELECTs first to try and reduce the number of extraneous operations we do.
This commit is contained in:
@@ -489,7 +489,8 @@ def db2py(val, kind):
|
||||
|
||||
return val
|
||||
|
||||
def set_data(table, thing_id, **vals):
|
||||
|
||||
def update_data(table, thing_id, **vals):
|
||||
transactions.add_engine(table.bind)
|
||||
|
||||
u = table.update(sa.and_(table.c.thing_id == thing_id,
|
||||
@@ -510,6 +511,22 @@ def set_data(table, thing_id, **vals):
|
||||
|
||||
return len(inserts)
|
||||
|
||||
|
||||
def create_data(table, thing_id, **vals):
|
||||
transactions.add_engine(table.bind)
|
||||
|
||||
inserts = []
|
||||
for key, val in vals.iteritems():
|
||||
val, kind = py2db(val, return_kind=True)
|
||||
inserts.append(dict(key=key, value=val, kind=kind))
|
||||
|
||||
if inserts:
|
||||
i = table.insert(values=dict(thing_id=thing_id))
|
||||
i.execute(*inserts)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def incr_data_prop(table, type_id, thing_id, prop, amount):
|
||||
t = table
|
||||
transactions.add_engine(t.bind)
|
||||
@@ -554,9 +571,13 @@ def get_data(table, thing_id):
|
||||
|
||||
return res
|
||||
|
||||
def set_thing_data(type_id, thing_id, **vals):
|
||||
def set_thing_data(type_id, thing_id, brand_new_thing, **vals):
|
||||
table = get_thing_table(type_id, action = 'write')[1]
|
||||
return set_data(table, thing_id, **vals)
|
||||
|
||||
if brand_new_thing:
|
||||
return create_data(table, thing_id, **vals)
|
||||
else:
|
||||
return update_data(table, thing_id, **vals)
|
||||
|
||||
def incr_thing_data(type_id, thing_id, prop, amount):
|
||||
table = get_thing_table(type_id, action = 'write')[1]
|
||||
@@ -589,9 +610,13 @@ def get_thing(type_id, thing_id):
|
||||
res[row.thing_id] = stor
|
||||
return res
|
||||
|
||||
def set_rel_data(rel_type_id, thing_id, **vals):
|
||||
def set_rel_data(rel_type_id, thing_id, brand_new_thing, **vals):
|
||||
table = get_rel_table(rel_type_id, action = 'write')[3]
|
||||
return set_data(table, thing_id, **vals)
|
||||
|
||||
if brand_new_thing:
|
||||
return create_data(table, thing_id, **vals)
|
||||
else:
|
||||
return update_data(table, thing_id, **vals)
|
||||
|
||||
def incr_rel_data(rel_type_id, thing_id, prop, amount):
|
||||
table = get_rel_table(rel_type_id, action = 'write')[3]
|
||||
|
||||
@@ -234,6 +234,9 @@ class DataThing(object):
|
||||
def _commit(self, keys=None):
|
||||
if not self._created:
|
||||
self._create()
|
||||
just_created = True
|
||||
else:
|
||||
just_created = False
|
||||
|
||||
with g.make_lock('commit_' + self._fullname):
|
||||
if not self._sync_latest():
|
||||
@@ -259,6 +262,7 @@ class DataThing(object):
|
||||
if data_props:
|
||||
useless_updates = self._set_data(self._type_id,
|
||||
self._id,
|
||||
just_created,
|
||||
**data_props)
|
||||
else:
|
||||
useless_updates = 0
|
||||
|
||||
Reference in New Issue
Block a user