ORM dont kill your DB, developers do

Click here to load reader

  • date post

    09-May-2015
  • Category

    Technology

  • view

    7.787
  • download

    2

Embed Size (px)

description

Presentation gave at ConFoo 2012 (2012-03-01)As soon as you decide to use an ORM tool, one of the biggest factors is Rapid Application Development.Everything is wonderful during development phase, but when it hits production, performance doesn't work like you expect.You may think it's ORM's fault, your expected it to write as efficient queries as you manually do, but like guns, ORMs don't kill your database, developers do!This talk will go deep into Doctrine 2 ORM by exploring performance tips that can save your application from its deepest nightmare.

Transcript of ORM dont kill your DB, developers do

  • 1.ORMDatabaseDevelopershttp://www.ickr.com/photos/hoyvinmayvin/5103806609/ Guilherme BlancoThursday, March 1, 2012

2. ORMs dont kill your DB, developers do! @guilhermeblanco http://github.com/guilhermeblanco InstaClick Inc. Learning about good ORM practices on @guilhermeblancotalk at @confooca!Thursday, March 1, 2012 3. Agendahttp://www.ickr.com/photos/emerzh/3072428824/Thursday, March 1, 2012 4. General Rule RTFMThursday, March 1, 2012 5. Dependency managementhttp://www.ickr.com/photos/ollesvensson/3694625903/Thursday, March 1, 2012 6. Dependency ManagementThursday, March 1, 2012 7. Dependency ManagementnamespaceAppBundleBlogBundleEntity;/***@ORMEntity*/classPost{/***@ORMOneToMany(*targetEntity="AppComment:Comment",*mappedBy="post"*)*/protected$comments;}namespaceAppBundleCommentBundleEntity;/***@ORMEntity*/classComment{/***@ORMManyToOne(*targetEntity="AppBlog:Post",*inversedBy="comments"*) */protected$post;}Thursday, March 1, 2012 8. Dependency ManagementThursday, March 1, 2012 9. Dependency ManagementThursday, March 1, 2012 10. Dependency ManagementnamespaceAppBundleBlogBundleEntity;/***@ORMEntity*/classPost{//...}namespaceAppBundleCommentBundleEntity;/***@ORMEntity*/classComment{/***@ORMManyToOne(targetEntity="AppBlog:Post")*/protected$post;}Thursday, March 1, 2012 11. Fetch Modehttp://www.ickr.com/photos/comedynose/5318259802/Thursday, March 1, 2012 12. Fetch Mode A fetching strategy is what ORM will use to retrieveassociated objects if the application needs to navigate through themThursday, March 1, 2012 13. Fetch ModeSupported by all association types...Thursday, March 1, 2012 14. Fetch Mode OneToOne OneToMany ManyToOne ManyToManyThursday, March 1, 2012 15. Fetch ModeAvailable fetch modes...Thursday, March 1, 2012 16. Fetch Mode EAGER LAZY (default) EXTRA_LAZYThursday, March 1, 2012 17. Fetch ModeAn association (collection or attribute), is fetched immediately when owner is loaded EAGER LAZY (default) EXTRA_LAZYThursday, March 1, 2012 18. Fetch ModeAn association (collection or attribute), is fetched immediately when owner is loaded EAGER An association (collection or attribute), LAZY (default)is fetched when the application invokes an operation over it EXTRA_LAZYThursday, March 1, 2012 19. Fetch ModeAn association (collection or attribute), is fetched immediately when owner is loaded EAGER An association (collection or attribute), LAZY (default)is fetched when the application invokes an operation over it EXTRA_LAZYIndividual elements from association are accessed from Database as needed. ORMdoes not fetch the whole association unless it is absolutely necessaryThursday, March 1, 2012 20. Fetch Mode/***@ORMEntity*/classPost{/***@ORMManyToOne(targetEntity="User",fetchMode="EAGER")*/protected$author;/***@ORMManyToMany(targetEntity="Tags",fetchMode="EXTRA_LAZY")*@ORMJoinTable(name="posts_tags")*/protected$tagList;}/***@ORMEntity*/classComment{/***@ORMOneToMany(targetEntity="Post",fetchMode="LAZY")*@JoinColumn(name="post_id",referencedColumnName="id")*/protected$post;}Thursday, March 1, 2012 21. Fetch Mode/***@ORMEntity*/Deadly sinclassPost{/***@ORMManyToOne(targetEntity="User",fetchMode="EAGER")*/protected$author;/***@ORMManyToMany(targetEntity="Tags",fetchMode="EXTRA_LAZY")*@ORMJoinTable(name="posts_tags")*/protected$tagList;}/***@ORMEntity*/classComment{/***@ORMOneToMany(targetEntity="Post",fetchMode="LAZY")*@JoinColumn(name="post_id",referencedColumnName="id")*/protected$post;}Thursday, March 1, 2012 22. Queryinghttp://www.ickr.com/photos/pschadler/4932737690/Thursday, March 1, 2012 23. Querying$query=$entityManager->createQuery(SELECTpFROMPostp);$postList=$query->getResult();foreach($postListas$post){$tagList=$post->getTagList();foreach($tagListas$tag){echo$tag->getName();}}Thursday, March 1, 2012 24. Querying$query=$entityManager->createQuery(SELECTpFROMPostp);$postList=$query->getResult();foreach($postListas$post){$tagList=$post->getTagList(); N + 1 trolls?foreach($tagListas$tag){echo$tag->getName();}}Thursday, March 1, 2012 25. Querying$query=$entityManager->createQuery(SELECTp,tFROMPostpLEFTJOINp.tagListt);$postList=$query->getResult();foreach($postListas$post){$tagList=$post->getTagList();foreach($tagListas$tag){echo$tag->getName();}}Thursday, March 1, 2012 26. Querying$query=$entityManager->createQuery(SELECTp,tFROMPostpPardon? DQL isLEFTJOINp.tagListt);powerful! RTFM$postList=$query->getResult();foreach($postListas$post){$tagList=$post->getTagList();foreach($tagListas$tag){echo$tag->getName();}}Thursday, March 1, 2012 27. QueryingI know you all dont trust me...Thursday, March 1, 2012 28. Querying...but take a look at its EBNF grammar...Thursday, March 1, 2012 29. QueryLanguage::= SelectStatement | UpdateStatement | DeleteStatement SelectStatement::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] UpdateStatement::= UpdateClause [WhereClause] DeleteStatement::= DeleteClause [WhereClause] JoinAssociationPathExpression::= IdentificationVariable "." (CollectionValuedAssociationField | SingleValuedAssociationField) AssociationPathExpression::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression StateFieldPathExpression ::= IdentificationVariable "." StateField | SingleValuedAssociationPathExpression "." StateField SingleValuedAssociationPathExpression::= IdentificationVariable "." SingleValuedAssociationField CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField StateField ::= {EmbeddedClassStateField "."}* SimpleStateField SimpleStateFieldPathExpression ::= IdentificationVariable "." StateField SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}* SimpleSelectClause ::= "SELECT" ["DISTINCT"] SimpleSelectExpression UpdateClause ::= "UPDATE" AbstractSchemaName ["AS"] AliasIdentificationVariable "SET" UpdateItem {"," UpdateItem}* DeleteClause ::= "DELETE" ["FROM"] AbstractSchemaName ["AS"] AliasIdentificationVariable FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}* SubselectFromClause::= "FROM" SubselectIdentificationVariableDeclaration {"," SubselectIdentificationVariableDeclaration}* WhereClause::= "WHERE" ConditionalExpression HavingClause ::= "HAVING" ConditionalExpression GroupByClause::= "GROUP" "BY" GroupByItem {"," GroupByItem}* OrderByClause::= "ORDER" "BY" OrderByItem {"," OrderByItem}* Subselect::= SimpleSelectClause SubselectFromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] UpdateItem ::= IdentificationVariable "." (StateField | SingleValuedAssociationField) "=" NewValue OrderByItem::= (ResultVariable | SingleValuedPathExpression) ["ASC" | "DESC"] GroupByItem::= IdentificationVariable | SingleValuedPathExpression NewValue ::= ScalarExpression | SimpleEntityExpression | "NULL" IdentificationVariableDeclaration::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}* SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration | (AssociationPathExpression ["AS"] AliasIdentificationVariable) JoinVariableDeclaration::= Join [IndexBy] RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression ["AS"] AliasIdentificationVariable ["WITH" ConditionalExpression] IndexBy::= "INDEX" "BY" SimpleStateFieldPathExpression SelectExpression ::= IdentificationVariable | PartialObjectExpression | (AggregateExpression | "(" Subselect ")" | FunctionDeclaration | ScalarExpression) [["AS"] AliasResultVariable] SimpleSelectExpression ::= ScalarExpression | IdentificationVariable | (AggregateExpression [["AS"] AliasResultVariable]) PartialObjectExpression::= "PARTIAL" IdentificationVariable "." PartialFieldSet PartialFieldSet::= "{" SimpleStateField {"," SimpleStateField}* "}" ConditionalExpression::= ConditionalTerm {"OR" ConditionalTerm}* ConditionalTerm::= ConditionalFactor {"AND" ConditionalFactor}* ConditionalFactor::= ["NOT"] ConditionalPrimary ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")" SimpleConditionalExpression::= ComparisonExpression | BetweenExpression | LikeExpression | InExpression | NullComparisonExpression |ExistsExpression | EmptyCollectionComparisonExpression | CollectionMemberExpression | InstanceOfExpression EmptyCollectionComparisonExpression::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY" CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression Literal::= string | char | integer | float | boolean InParameter::= Literal | InputParameter InputParameter ::= PositionalParameter | NamedParameter PositionalParameter::= "?" integer NamedParameter ::= ":" string ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")" SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}* ArithmeticTerm ::= ArithmeticFactor {("*" | "/") ArithmeticFactor}* ArithmeticFactor ::= [("+" | "-")] ArithmeticPrimary ArithmeticPrimary::= SingleValuedPathExpression | Literal | "(" SimpleArithmeticExpression ")" | FunctionsReturningNumerics | AggregateExpression |FunctionsReturningStrings | FunctionsReturningDatetime | IdentificationVariable | InputParameter | CaseExpression ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary | StateFieldPathExpression | BooleanPrimary | EntityTypeExpression | CaseExpression StringExpression ::= StringPrimary | "(" Subselect ")" StringPrimary::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression | CaseExpression BooleanExpression::= BooleanPrimary | "(" Subselect ")" BooleanPrimary ::= StateFieldPathExpression | boolean | InputParameter EntityExpression ::= SingleVa