Commit a08a3c33 authored by Vincent Pelletier's avatar Vincent Pelletier

Base_generateTicketUseDomain: Accelerate on large document sets.

The set of resources correponding to a given (non-strict) use is generally
constant, while the number of documents having relations to these
resources will increase over a site's life.

The original query used 2 joins:
- catalog to category for document/resource relation
- category to category for resource/use relation

Given several tables joined together, MySQL query optimiser will try
to first execute a query on the table which will yield the fewest rows.

As a result of all the above, query optimiser would end up choosing to
first find which resources have a use relation to given uid, and only after
find which documents have a resource relation to these. Which means it
cannot use any index on the documents themselves, and only an index
on resource's use... Leading to extremely poor performance on large data
set when, for example, trying to list the few documents in a given state
which also have a resource of selected use.

Instead, lookup the list of resources per (non-strict) use when building
the domain tree, and put that pre-computed uid list as membership
criterion: catalog query is then only a single-join, whose execution is
trivial to plan.
parent e305f0aa
...@@ -9,6 +9,10 @@ else: ...@@ -9,6 +9,10 @@ else:
return () return ()
child_list, resource_list = portal.portal_categories.use.restrictedTraverse(category_relative_url).Category_getUseCategoryListAndResourceList() child_list, resource_list = portal.portal_categories.use.restrictedTraverse(category_relative_url).Category_getUseCategoryListAndResourceList()
domain_list = [] domain_list = []
if child_list:
resource_uid_by_use_uid_dict = {}
for row in portal.portal_catalog(select_list=['default_use_uid'], default_use_uid=[x.getUid() for x in child_list]):
resource_uid_by_use_uid_dict.setdefault(row.default_use_uid, []).append(row.uid)
for child in child_list: for child in child_list:
domain = parent.generateTempDomain(id=child.getId()) domain = parent.generateTempDomain(id=child.getId())
domain.edit( domain.edit(
...@@ -16,8 +20,8 @@ for child in child_list: ...@@ -16,8 +20,8 @@ for child in child_list:
membership_criterion_category=(child.getRelativeUrl(), ), membership_criterion_category=(child.getRelativeUrl(), ),
domain_generator_method_id=script.id, domain_generator_method_id=script.id,
) )
domain.setCriterionPropertyList(['related_resource_from_use_category_uid']) domain.setCriterionPropertyList(['strict_resource_uid'])
domain.setCriterion('related_resource_from_use_category_uid', identity=child.getUid()) domain.setCriterion('strict_resource_uid', identity=resource_uid_by_use_uid_dict[child.getUid()])
domain_list.append(domain) domain_list.append(domain)
for resource in resource_list: for resource in resource_list:
domain = parent.generateTempDomain(id=resource.getId()) domain = parent.generateTempDomain(id=resource.getId())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment