[IMP] core: create/drop indexes all at once

Reduce the number of queries to create and drop indexes.

This saves 1.5% of the total installation time.

X-original-commit: 0e1e480da9d971575feba64038c4fa518ebe102b
This commit is contained in:
Raphael Collet
2020-04-03 11:40:29 +00:00
parent 3ecb6fdcb0
commit e0c2dde324
2 changed files with 34 additions and 19 deletions
+2 -18
View File
@@ -780,10 +780,10 @@ class Field(MetaField('DummyField', (object,), {})):
column = columns.get(self.name)
# create/update the column, not null constraint, indexes
# create/update the column, not null constraint; the index will be
# managed by registry.check_indexes()
self.update_db_column(model, column)
self.update_db_notnull(model, column)
self.update_db_index(model, column)
return not column
@@ -831,22 +831,6 @@ class Field(MetaField('DummyField', (object,), {})):
elif not self.required and has_notnull:
sql.drop_not_null(model._cr, model._table, self.name)
def update_db_index(self, model, column):
""" Add or remove the index corresponding to ``self``.
:param model: an instance of the field's model
:param column: the column's configuration (dict) if it exists, or ``None``
"""
indexname = '%s_%s_index' % (model._table, self.name)
if self.index:
try:
with model._cr.savepoint(flush=False):
sql.create_index(model._cr, indexname, model._table, ['"%s"' % self.name])
except psycopg2.OperationalError:
_schema.error("Unable to add index for %s", self)
else:
sql.drop_index(model._cr, indexname, model._table)
############################################################################
#
# Read from/write to database
+32 -1
View File
@@ -14,11 +14,13 @@ import logging
import os
import threading
import psycopg2
import odoo
from .. import SUPERUSER_ID
from odoo.sql_db import TestCursor
from odoo.tools import (assertion_report, config, existing_tables, ignore,
lazy_classproperty, lazy_property, OrderedSet)
lazy_classproperty, lazy_property, sql, OrderedSet)
from odoo.tools.lru import LRU
_logger = logging.getLogger(__name__)
@@ -375,6 +377,8 @@ class Registry(Mapping):
self._ordinary_tables = None
self.check_indexes(cr, model_names)
while self._post_init_queue:
func = self._post_init_queue.popleft()
func()
@@ -384,6 +388,33 @@ class Registry(Mapping):
# make sure all tables are present
self.check_tables_exist(cr)
def check_indexes(self, cr, model_names):
""" Create or drop column indexes for the given models. """
expected = [
("%s_%s_index" % (Model._table, field.name), Model._table, field.name, field.index)
for model_name in model_names
for Model in [self.models[model_name]]
if Model._auto and not Model._abstract
for field in Model._fields.values()
if field.column_type and field.store
]
if not expected:
return
cr.execute("SELECT indexname FROM pg_indexes WHERE indexname IN %s",
[tuple(row[0] for row in expected)])
existing = {row[0] for row in cr.fetchall()}
for indexname, tablename, columnname, index in expected:
if index and indexname not in existing:
try:
with cr.savepoint(flush=False):
sql.create_index(cr, indexname, tablename, ['"%s"' % columnname])
except psycopg2.OperationalError:
_schema.error("Unable to add index for %s", self)
elif not index and indexname in existing:
sql.drop_index(cr, indexname, tablename)
def check_tables_exist(self, cr):
"""
Verify that all tables are present and try to initialize those that are missing.