From reading the docs in Grails I found the following statement:
However, excessive use of inheritance and table-per-subclass can result in poor query performance due to the use of outer join queries. In general our advice is if you're going to use inheritance, don't abuse it and don't make your inheritance hierarchy too deep.
My question is: how deep is too deep?
Will 5 extensions in an inheritance chain make Grails cry?, 10?, 20?... what is the criteria to determine this?, or do we know if there is a clear way to extrapolate such performance degradation?
How deep is too deep? is a rather subjective question. But, it's possible to make an educated guess when you consider what happens at the database level with table-per-subclass inheritance. Lets assume you have these domain classes:
class Employee {
String firstName
String lastName
static constraints = {
}
static mapping = {
tablePerHierarchy false
}
}
class Supervisor extends Employee {
String office
static constraints = {
}
}
You'd end up with two tables: EMPLOYEE
and SUPERVISOR
. The EMPLOYEE
table would contain the columns id
, first_name
, and last_name
. But notice that the SUPERVISOR
table would only contain the columns id
and office
.
This means that to retrieve a Supervisor
GORM has to join both tables in order to populate the inherited properties.
SELECT EMPLOYEE.ID, FIRST_NAME, LAST_NAME, OFFICE
FROM SUPERVISOR INNER JOIN EMPLOYEE
ON SUPERVISOR.ID = EMPLOYEE.ID
It's these joins which have the potential to result in reduced performance. As you can imagine, 10 or 20 levels of inheritance would be disastrous. Yet a few, especially if the tables are small, would likely be OK.
Besides, a deep inheritance hierarchy is a sign that something is probably wrong with the domain model architecture (ie. consider using Traits).
You can read more about both forms of inheritance in my article here.