Most Powerful Open Source ERP

Predicates Performances

This discussion is intended to track what are the current issues with predicate searching and help defining a solution.
  • Last Update:2016-05-16
  • Version:001
  • Language:en

This discussion is intended to track what are the current issues with predicate searching and help defining a solution.

Table of Contents

Note

This discussion is intended to track what are the current issues with predicate searching (DomainTool's generateMappedValue and searchPredicateList) and help defining a solution

Example

This is what a predicate search currently looks like

  SELECT DISTINCT
   catalog.path,   catalog.uid
  FROM
   roles_and_users AS related_roles_and_users_0, catalog AS catalog, predicate_category AS predicate_category, predicate AS predicate
  WHERE
   1 = 1
   AND ((( (predicate.quantity is NULL) AND (predicate.quantity_range_min is NULL) AND (predicate.quantity_range_max is NULL)OR (predicate.quantity = '1.0') OR (predicate.quantity_range_min <= '1.0') AND 
  (predicate.quantity_range_max is NULL) OR (predicate.quantity_range_min is NULL) AND predicate.quantity_range_max > '1.0' OR (predicate.quantity_range_min <= '1.0') AND predicate.quantity_range_max > 
  '1.0'  ) AND
  ( (predicate.start_date is NULL) AND (predicate.start_date_range_min is NULL) AND (predicate.start_date_range_max is NULL) )) AND
  ((predicate_category.category_uid = 6601 AND predicate_category.base_category_uid = 882) OR (predicate_category.category_uid = 4446 AND predicate_category.base_category_uid = 4495))) AND (predicate.uid 
  != '0' AND predicate_category.uid != '0' AND (related_roles_and_users_0.allowedRolesAndUsers = 'Member' OR related_roles_and_users_0.allowedRolesAndUsers = 'Manager' OR 
  related_roles_and_users_0.allowedRolesAndUsers = 'Authenticated' OR related_roles_and_users_0.allowedRolesAndUsers = 'Anonymous' OR related_roles_and_users_0.allowedRolesAndUsers = 'user:alex' OR 
  related_roles_and_users_0.allowedRolesAndUsers = 'user:role:Anonymous' OR related_roles_and_users_0.allowedRolesAndUsers = 'user:role:Authenticated') AND catalog.has_cell_content = 0 AND *
  (catalog.portal_type = 'Purchase Supply Cell' OR catalog.portal_type = 'Purchase Supply Line' OR catalog.portal_type = 'Sale Supply Cell' OR catalog.portal_type = 'Sale Supply Line' OR 
  catalog.portal_type = 'Supply Cell' OR catalog.portal_type = 'Supply Line') AND catalog.uid = predicate_category.uid AND catalog.uid = predicate.uid AND 
  related_roles_and_users_0.uid = catalog.security_uid)
  LIMIT 1000

SQL

currently, there are two tables:

  • - predicate (uid, quantity, quantity_range_min, quantity_range_max, start_date, start_date_range_min, start_date_range_max) - predicate_category (uid, category_uid, base_category_uid, category_strict_membership)

The sql query currently matches all predicates that satify these condition :

  • - context quantity is within the range defined on the predicate - context start_date is within the range defined on the predicate - context category is present on the predicate

The test method is then called on all retrieved predicates, as a second level of filtering, and the list of predicates whose test method passes is then returned.

Explanation

The problem is that if context has more than one category, the SQL query will try to match them using 'OR' in between. So, for a sales order line with a resource, a destination, and some variations and options, we will have to test all the predicates that match the resource, or the destination, or any variation or option.

In a system where we deal with resources which share some of their variations (color, size), we will quickly select a huge amount of unneeded predicates (eg. all that have resource/shirt, plus all that have color/blue, plus all that have size/42) on which we will have to call the test method.

One sure thing is that we cannot expect all categories to be here all the time. for example variations and options are not present when retrieving the base_price from the line predicate, and options (maybe variations also) on predicates are mutually exclusive (cell predicates like additional price will only define one of them at a time)

One idea could be to force some categories, like resource, which should always be present in a predicate.getAcquiredCategoryList(), but the rule is not as simple as "force all categories that are not a variationor option", as for destination, we can have a predicate which does not define a destination, if we want it to be used for all customers.

Related Articles