We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    I’m working through some Snippets and Custom Manager Pages, and I’ve been updating my xPDO XML schema and the related PHP classes/maps.... and I’ve noticed that the performance of my CMP’s has slowed to a crawl after introducing a few composite/aggregate relationships. Is it possible that the decrease in performance is due to me screwing up something in my schema? Or is it possible that a legitimate XML creates poor performance via these relationships? Or... it could totally be my own dumb mistake somewhere in my code.

    Thoughts?
      • 21257 MODX Staff
      • 730 Posts
      Once you get to your CMPs, XML is not part of the equation. The object metadata is mapped into php arrays in the map files. (Unless your CMPs are related to parsing XML files.)
      I would think you’d only see a performance problem if you were loading up huge collections into memory at once (involving many/deep relationships or not).
        Mike Schell
        Lead Developer, MODX Cloud
        Email: [email protected]
        GitHub: https://github.com/netProphET/
        Twitter: @mkschell
        • 22303 MODX Staff
        • 10,725 Posts
        Having the relationships defined does not automatically generate code that will make the code you write efficient. Are you using the getCollectionGraph() and getObjectGraph() methods to get the related objects in a single query? Are you using getOne() or getMany() in a loop (Jason hope’s not)? Did you properly define your indexes and are they showing up on the database tables when you create them? There are a lot of things involved here...
          • 9207 ☆ A M B ☆
          • 2,475 Posts
          netProphET: after updating my XML and regenerating the PHP class/maps, that’s when performance started suffering. So no, it’s not directly related to the XML, but it does seem that defining more (or incorrect?) relationships has something to do with it.

          Jason: Yeah, unfortunately, there are some cases where I’m using getOne inside of a loop (don’t know how else to handle it, frankly -- maybe it’s time to use the getCollectionGraph). E.g. I’m listing all rows from a custom table -- the db table by itself is not human readable, so I need to track down some of the foreign keys in order to list the human-readable columns inferred by the foreign keys.

          BUT that’s not the area where performance is suffering, oddly... I’m not using the getCollectionGraph or getObjectGraph methods yet. Some of these relationships are difficult to work with if you retrieve more than a layer deep, you know? E.g. if you join on a related table, which in turn contains foreign keys, then it starts getting wonky.

          Mostly, it’s a lot of stuff like this:
          $tf = $modx->getObject('Trackingforms', $trackingform_id);
          		
          $forms_resources = $tf->getMany('Resources');
          foreach ( $forms_resources as $fr )
          {
          	$resource_id = $fr->get('resource_id');
          	// ... do stuff ... 
          }


          I’ve got a version of this working (albeit slowly) but I think I’d better give it a round 2 and approach it from a more architecturally sound way. Hard to explain exactly what I mean, but I’ve created a form that is perhaps easier for the user, but is not so "honest" as far as what’s in the database. I have a feeling that round 2 will be considerably faster.


            • 28215
            • 4,149 Posts
            Always approach any page loading scripts that query to GET records from the database with this mindset: "1 query only".

            If you’re having to do more than one query, you’re probably doing something wrong in DB structure, your calls, or logically.

            You should look into getCollectionGraph.
              shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
              • 9207 ☆ A M B ☆
              • 2,475 Posts
              I agree Shaun... I try to do it in one query when possible, but sometimes I make concessions when dealing with a framework.

              Did something change with the rtfm.modx.com site? I was gonna update some of the docs, but I can’t log in...
                • 28215
                • 4,149 Posts
                You should be able to login now; we had some DNS issues earlier this week. If not let me know.
                  shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
                  • 9207 ☆ A M B ☆
                  • 2,475 Posts
                  Thanks Shaun -- I’m able to log in now.

                  But one question: using getCollectionGraph, how I correctly handle a one to many relationship?

                  E.g. in this code, a TrackingForm has one client, but many resources:

                  $tfs = $modx->getCollectionGraph('Trackingforms', '{"Client": {}, "Resources": {} }', $trackingform_id);
                  
                  foreach ( $tfs as $tf )
                  {
                  	$x = '';
                  	foreach ( $tf->Resources as $r )
                  	{
                  		$x .= $r->get('name'); // <-- does not work
                  	}
                  	$name = $tf->Client->get('name'); // <-- this works fine
                  	
                  }


                  I think I have a relationship defined incorrectly... still working, but I think I’m close.