Skip to content

Extrem long save time at save items at BE #1153

Open

Description

@zonky2

look at contao-community-alliance/dc-general#201

we found the first bottle necks...

1.) ToolboxFile.php

public static function convertValueToPath($varValue)

    public static function convertValueToPath($varValue)
    {
+        if (empty($varValue)) {
+            return '';
+        }
        $objFiles = FilesModel::findByPk($varValue);

2.) with "MM-1" and attribute select to "MM-2" which also a have relation per select to "MM-3" we found a strong increase of database queries... may be, we can "cache" all existing queries

public function getIdsFromFilter($objFilter, $strSortBy = '', $intOffset = 0, $intLimit = 0, $strSortOrder = 'ASC')

...
   /**
     * The service container.
     *
     * @var IMetaModelsServiceContainer
     */
    protected $serviceContainer;
+
+    private $existingIds = [];

...

    public function getIdsFromFilter($objFilter, $strSortBy = '', $intOffset = 0, $intLimit = 0, $strSortOrder = 'ASC')
    {
        $arrFilteredIds = $this->getMatchingIds($objFilter);

        // If desired, sort the entries.
        if ($arrFilteredIds && $strSortBy != '') {
            if ($objSortAttribute = $this->getAttribute($strSortBy)) {
                $arrFilteredIds = $objSortAttribute->sortIds($arrFilteredIds, $strSortOrder);
            } elseif (in_array($strSortBy, array('id', 'pid', 'tstamp', 'sorting'))) {
+                if (array_intersect($arrFilteredIds, $this->existingIds) == $arrFilteredIds) {
+                    return $arrFilteredIds;
+                }
                // Sort by database values.
                $arrFilteredIds = $this
                    ->getDatabase()
                    ->prepare(
                        sprintf(
                            'SELECT id FROM %s WHERE id IN(%s) ORDER BY %s %s',
                            $this->getTableName(),
                            $this->buildDatabaseParameterList($arrFilteredIds),
                            $strSortBy,
                            $strSortOrder
                        )
                    )
                    ->execute($arrFilteredIds)
                    ->fetchEach('id');
+                $this->existingIds = array_merge($this->existingIds, $arrFilteredIds);
            } elseif ($strSortBy == 'random') {
                shuffle($arrFilteredIds);
            }
        }
...

Activity

  1. added
    bugA bug! A bug! Fast, squish it!
    on May 25, 2017
  2. added this to the 2.1.0 milestone on May 25, 2017
  3. Damsgit commented on May 29, 2017

    @Damsgit

    I have this message :
    Fatal error: Cannot redeclare MetaModels\MetaModel::$serviceContainer in /homepages/4/d406509772/htdocs/.../system/modules/metamodels/classes/src/MetaModels/MetaModel.php on line 692

    I can't clear this line ?
    protected $serviceContainer;

    I noted that the save time increases when i have a lot of items in MM (5000 or 10 000 items) before or after the changes.

  4. zonky2 commented on May 29, 2017

    @zonky2
    ContributorAuthor

    add only private $existingIds = [];

  5. modified the milestones: 2.1.0, 2.2.0 on Mar 14, 2018
  6. richardhj commented on Aug 3, 2018

    @richardhj
    Member

    I have one page that accesses different MetaModels. It uses about 1200 database queries to load the site (Contao 4 / Symfony debug console).
    I changed the following in the MetaModel.php and was able to reduce the number of database queries to about 400(!!!).

    +   private $cache;
    
        public function findById($intId, $arrAttrOnly = array())
        {
             if (!$intId) {
                 return null;
             }
    +
    +        if (isset($this->cache[$intId])) {
    +            return $this->cache[$intId];
    +        }
    +
             $objItems = $this->getItemsWithId(array($intId), $arrAttrOnly);
             if ($objItems && $objItems->first()) {
    -            return $objItems->getItem();
    +            $this->cache[$intId] = $objItems->getItem();
    +            return $this->cache[$intId];
             }
             return null;
         }

    Maybe there is a way to reach the same result by using doctrine cache / APCu??

  7. zonky2 commented on Aug 3, 2018

    @zonky2
    ContributorAuthor

    may be it´s a good idea to equalize the terms private $cache; to private $existingIds = [];

  8. discordier commented on Aug 3, 2018

    @discordier
    Member

    @richardhj Your change introduces a problem when $attrOnly is not empty, therefore we can not walk down that road. 😿

  9. richardhj commented on Aug 3, 2018

    @richardhj
    Member

    @discordier Did you ever enabled APCu doctrine cache? Is this available for Contao?

  10. modified the milestones: 2.2.0, 2.1.0 on Aug 3, 2018
  11. 26 remaining items

  12. zonky2 commented on Jan 23, 2022

    @zonky2
    ContributorAuthor

    As mentioned in #1352:

    Fixed in MM 2.2

  13. zonky2 commented on Jan 23, 2022

    @zonky2
    ContributorAuthor
  14. modified the milestones: 2.2.0, 2.3.0 on May 8, 2022
  15. zonky2 commented on Aug 23, 2022

    @zonky2
    ContributorAuthor

    Currently there is still the problem in the BE, if many attributes are selected to the filter and there are many items...

    @discordier has solution proposals for this

  16. modified the milestones: 2.3.0, 3.0.0, 2.2.6 on Jan 8, 2023
  17. modified the milestones: 2.3.0, 3.0.0 on Mar 2, 2023
  18. added
    enhancementThis issue is about an enhancement (aka new feature)
    and removed
    bugA bug! A bug! Fast, squish it!
    on Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementThis issue is about an enhancement (aka new feature)

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions