我有大量对象需要通过sqlalchemy插入到Oracle数据库中。
使用单独的插入需要相当长的时间才能执行。在周围搜索之后,很明显还有更有效的批量插入方法,如bulk_insert_mappings、bulk_save_objects等。这些方法比单独的插入执行得更好。然而,我注意到他们似乎将插入内容批量处理成8个左右的分组。是否有可能将此批大小增加到1000左右?
我一直使用的性能文档是:http://docs.sqlalchemy.org/en/latest/faq/performance.html
render_nulls标志似乎没有效果。如果有用的话,我正在使用cx_Oracle驱动程序。
如需额外参考:
session.bulk_insert_mappings(MY_OBJECT, my_object_dicts_for_insert)
生成由"after_cursor_execute“事件度量的关于len(my_object_dicts_for_insert)/8语句。有没有办法从sqlalchemy或数据库中调优此行为?
谢谢!
发布于 2018-02-20 23:28:47
问题出在我对render_nulls标志的理解上。
从描述中,我认为如果提供了具有不同键的字典列表,那么它们将使用空值填充,以允许单个insert语句。
这不是它的工作方式,您必须确保您的字典列表具有相同的键,并且您使用无填充未使用的字段。然后,当render_nulls设置为True时,NULL值将被插入到具有None值的列中,从而允许使用一条insert语句。
示例:
# This results in 2 inserts
my_objects = [{'a': 1, 'b': 2}, {'a': 1}]
session.bulk_insert_mappings(MY_OBJECT, my_objects, render_nulls=True)
# This results in 2 inserts
my_objects = [{'a': 1, 'b': 2}, {'a': 1}]
session.bulk_insert_mappings(MY_OBJECT, my_objects, render_nulls=False)
# This results in 2 inserts
my_objects = [{'a': 1, 'b': 2}, {'a': 1, 'b': None}]
session.bulk_insert_mappings(MY_OBJECT, my_objects, render_nulls=False)
# This results in 1 insert - BETTER PERFORMANCE
my_objects = [{'a': 1, 'b': 2}, {'a': 1, 'b': None}]
session.bulk_insert_mappings(MY_OBJECT, my_objects, render_nulls=True)这导致了相当大的性能提升,对我来说,性能提高了大约10倍。
请注意,在使用render_nulls时可能会有副作用,请阅读此处的文档:http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.bulk_insert_mappings
如果你不能使用render_nulls标志,不能用None填充你的dicts,或者不想增加发送空值的带宽,你可以通过根据dict的键集对你的对象列表进行分组来提高执行插入的数量。
示例:
# This will result in 2 inserts - BETTER PERFORMANCE
my_objects = [{'a': 1, 'b': 2}, {'a': 2, 'b': 3}, {'a': 4}]
session.bulk_insert_mappings(MY_OBJECT, my_objects)
# This will result in 3 inserts
my_objects = [{'a': 1, 'b': 2}, {'a': 4}, {'a': 2, 'b': 3}]
session.bulk_insert_mappings(MY_OBJECT, my_objects)https://stackoverflow.com/questions/48874745
复制相似问题