tags:

views:

471

answers:

5

Say if I have a large dataset, the table has well over a million records and the database is normalized so theres foreign keys and stuff. Ive set up the relations properly and i get a list of the first object applications = EntityLoad("entityName") but because of the relations and stuff the page takes like 24 seconds to load, even when i limit the number of records to show to like 5 it takes an awful long time to load.

My solution to this was create another object that just gets the list, and then when the user wants to , use the object with all the relations and show it to the user. Is this the right way to approach it, or am i missing a big ORM concept?

+2  A: 

The first thing I would do is enable SQL logging in your Application.cfc. Add logSQL=true to This.ormSettings.

That should allow you to grab the SQL that ORM generates. Run it in an analyzer. See if the ORM SQL is doing somethign crazy. See if it is an index that you missed or something.

Also are you doing paging as Ray talks about here: http://www.coldfusionjedi.com/index.cfm/2009/8/14/Simple-ColdFusion-9-ORM-Paging-Demo?

If not have you tried using ORMExecuteQuery and HQL to enable paging.

Those are my thoughts.

Terry Ryan
+4  A: 

Are you counting just the time to get the data, or are you perhaps doing a CFDUMP on it or something else visually that could be slow. In other words, have you wrapped the EntityLoad by itself in a cftimer tag to be sure that it is the culprit?

CF Jedi Master
Ray That was the problem, I was cfdumping the thing and it wasnt lazy loading anything!. Thank you jedi master!
Faisal Abid
Great tip, thanks Ray
Jas Panesar
+1  A: 

Hi Faisal,

There is a good chance Hibernate is doing it's caching thing. A fair comparison in my mind (everyone please feel free to add) is doing an:

EntityLoad("entity_name") is the same as doing a select * from TABLE

So, in this case, what Hibernate might be doing in instantiating the memory, and caching it a certain way, your database server might do this similarly when you sent such a broad SQL instruction.

I have been extremely interested in ORM the past few weeks and it looks to be a very rewarding undertaking.

For this reason, is there a tiem you would ever load all 500,000 records as a result? I assume not.

I have one large logging table that I will be attacking, I am finding that the SQL good stuff must be there. For example, mark the fields that are indexes as such, this will speed it up incredibly when searching. I am sure the ORM can handle this.

Beyond this:

  • Find some excellent Hibernate forums, resources, and tutorials so you can learn Hibernate. This isn't really as much a Coldfusion --> ORM issue as what Hibernate might do on it's own. I have ordered a few Hibernate books that I'm waiting on to see how they are.
  • Likewise there seems to be an incredible amount of Hibernate resources out there where you can bring the Performance enhancement solutions of Hibernate into the Coldfusion sphere. I might be making it too simple, but I see the CF-ORM implementation as a wrapper with some code generation to save us time.
  • Take a look at implementing filters to cut down your data in the EntityLoad() call.
  • As recommended in other threads, turn on sql logging and see what sql is being generated. Chances are it might not be what you need. Check out HQL to see if you can form a better statement.
  • Most importantly, share what you find. I'll volunteer to do the same on this as you've tempted me to go try this out in my spare time a bit sooner than planned.
Jas Panesar
+1  A: 

Faisal, we ran into this with Linq (c# orm).

Our solution was to create simple objects not holding the relational data. For instance, along with Users we had a SimpleUsers object which held little or no relation to any other object and had a limited set of columns.

There could be other ways of handling this but this approach helped tremendously with the query speed.

johncblandii
Thanks for sharing John, that sounds very helpful.
Jas Panesar
No sweat Jas. I believe CF should hav ethe lazy=true working in the final build but for now I guess the beta isn't quite baked just yet. :-)
johncblandii
+1  A: 

When defining complex domain models with Hibernate - you will sometimes need to tweak the mapping to improve performance. This is especially true if you are dealing with inheritance (not sure how much inheritance is in your model). The ultimate goal is to have your query pulling from as few tables as possible while still preserving your domain model. This might require using the advanced inheritance mappings (more on that in a sec).

LOGGING SQL

As Terry mentioned, you will want to be sure you can log the actual SQL that is being passed to your database (yeah, you don't totally get away from SQL with ORM). Here is a great article on setting up logging for Hibernate in CF9 from Rupesh:

http://www.rupeshk.org/blog/index.php/2009/07/coldfusion-orm-how-to-log-sql/

HIBERNATE MAPPING FILES

Anytime you want to do something beyond the basic, you want to be sure that you are looking at the actual Hibernate mapping files that are generated for your CFC's. Be sure to set the following with all of your hibernate options in Application.cfc:

savemapping = true

While the cfproperty properties allow you to define many aspects of the mapping, there are actually some things that can only be done in the Hibernate mapping files (and there are tons of community resources on this.

INHERITANCE MAPPING

As I mentioned earlier, Hibernate provides different inheritance strategies for mapping. They are Table per Hierarchy, Table per subclass, Table per concrete class, and implicit polymorphism. You can read more about these types in the CF9 docs under Advanced Mapping > Inheritance Mapping or in the Hibernate documentation (as it would take forever to explain each of these).

Knowing how your tables are mapped is very important with inheritance (and it is also where Hibernate can generate some HUGE queries if you don't tweak your setup).

Those are the things I can think of - if you can give some additional information about your domain model - we can look to see what other things might be done to tweak it.

David Tucker