Slide 1

Slide 1 text

Eloquent for Advanced Querying Nemanja Marić maki10

Slide 2

Slide 2 text

About me ● PHP Developer at System Inc ● Member of PHP Serbia Community ● Co-organizer Laravel Serbia Meetup’s ● Working with PHP since 2014 ● In Laravel world from 2016 ● Open source contributor ● Co-owner Laravel open source Package `Laravel admin panel` ● Contributing to the Laravel Framework ● And most !important: Husband and father of two little angels

Slide 3

Slide 3 text

Interesting part Share your knowledge with others to get some knowledge

Slide 4

Slide 4 text

And story begins...

Slide 5

Slide 5 text

“Fictional Job”

Slide 6

Slide 6 text

The job ● Simple bootstrap layout ● Pagination ( 200 users per page ) ● Image, Name, Company, Birthday, last interactions ● Must be fast ● Must be over until 10 am GMT time zone, more than 6 hours left ● Be ready for additional features that we are will provide you

Slide 7

Slide 7 text

Job done ● Deployed after one hour of working ● Easy cash ● Wife calling to order some chinese food and opening champagne ● Im am the king

Slide 8

Slide 8 text

Disaster In 72 different language this means same. When you get this message, everything is clear. You f**ked up something. Spending next half hour explaining client that, that is temporarily fix only.

Slide 9

Slide 9 text

1. Users table for Auth 2. 10k Customers 3. 1 to 1 relation between Customer and Company 4. 1 to many relation between Customer and Interactions 5. Every customer have 30 Interactions

Slide 10

Slide 10 text

Debugging

Slide 11

Slide 11 text

Tools Everything that need for debugging is Only one package `Laravel Debugbar`. Made by Barry vd. Heuvel @barryvdh. Powerful tools with more than 6500 Stars. Following installation process and we are ready. For this talk we will only look at Query tab, memory, and Server response time. `

Slide 12

Slide 12 text

First reading (omg)

Slide 13

Slide 13 text

Ok, we are hit `N + 1` issue Basically `N+1` issue is type 1-to-many relationship It is much faster to get 1 query which returns 100 results than to get 100 queries which each return 1 result.

Slide 14

Slide 14 text

Let Eager load Companies

Slide 15

Slide 15 text

But how to implement Eager load? It is so simple, just add with(‘some relationship’ )

Slide 16

Slide 16 text

Add Last interaction date via eager load

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

But why eager load make so much memory leak?

Slide 19

Slide 19 text

It didn’t. Our approach is wrong.

Slide 20

Slide 20 text

Let’s try get last interaction via database query

Slide 21

Slide 21 text

Ok this is better but far from perfect. Still have too much query, and response time is more than 350ms. Can we make this to be better?

Slide 22

Slide 22 text

Yes, via subquery.

Slide 23

Slide 23 text

Add local scope and subQuery

Slide 24

Slide 24 text

Clear view and rerun the results

Slide 25

Slide 25 text

This is working great, but we use DB Query builder in our model. Can we make it look pretty and use Eloquent instead?

Slide 26

Slide 26 text

Yes, via Macro.

Slide 27

Slide 27 text

Let’s add macro then

Slide 28

Slide 28 text

New task arrived. Can we add `type` for Last Interaction?

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

Add new scope

Slide 31

Slide 31 text

Add type to view and rerun results again Ok, response is below 500 ms for 200 results, we can close one eye and this is still good result. Right?

Slide 32

Slide 32 text

No don’t close your eyes, just try making it better.

Slide 33

Slide 33 text

Let’s try eager load relationship

Slide 34

Slide 34 text

Update controller, view and rerun results

Slide 35

Slide 35 text

Ok, what happened now? Should we worry? - Our response time is lower, - Small memory increase, - And get extra query. Looks good to me.

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

Add “order by field”

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

Clickable table header

Slide 40

Slide 40 text

Add order by company Or we can use Macro for this job. Let’s add them.

Slide 41

Slide 41 text

Add in AppServiceProvider Update customer model as well

Slide 42

Slide 42 text

Add “order by birthday”

Slide 43

Slide 43 text

Add “order by last interaction date” scope

Slide 44

Slide 44 text

Add search for company or person name

Slide 45

Slide 45 text

Add scope for search

Slide 46

Slide 46 text

If your Sql have ability for full text search, consider using them Results for search params “ltd aida”

Slide 47

Slide 47 text

Add “birthday this weekend” filter

Slide 48

Slide 48 text

Update controller

Slide 49

Slide 49 text

Add scope for birthday this week We use Carbon to get date for weekends and make collection of dates in format ‘md’. Then via sql get results.

Slide 50

Slide 50 text

Limit view for moderators or admins

Slide 51

Slide 51 text

Pretty standard request. We can use policy which I think is great, or limiting access in blade view, or just tiny scope for eloquent.

Slide 52

Slide 52 text

Let’s use tiny scope

Slide 53

Slide 53 text

Update controller

Slide 54

Slide 54 text

Add visible to scope

Slide 55

Slide 55 text

Stored procedure

Slide 56

Slide 56 text

Definition of stored procedures A stored procedure is a segment of declarative SQL statements stored inside the database catalog. A stored procedure can be invoked by triggers, other stored procedures, and applications such as Java, Python, PHP. Advantages: 1. Typically stored procedures help increase the performance of the applications. 2. Stored procedures help reduce the traffic between application and database server 3. Stored procedures are secure. Disadvantages: 1. Stored procedure constructs are not designed for developing complex and flexible business logic 2. It is difficult to debug stored procedures 3. It is not easy to develop and maintain stored procedures.

Slide 57

Slide 57 text

Simple stored procedure

Slide 58

Slide 58 text

Simple?

Slide 59

Slide 59 text

Absolutely not!

Slide 60

Slide 60 text

Wrap up 1. Eloquent have built in support for stored procedure 2. The secret behind fast app, is memory usage and server response time 3. Always try to optimize your app. 4. Minimize query call. 5. Try to avoid using cache on N+1 issue 6. Use scopes because can be expanded with model or relationship. 7. Use naming conventions. 8. Chinese food doesn’t delivery to my place. 9. This talk is my point of view on Laracon 2018 talk by Jonathan Reinink @reinink

Slide 61

Slide 61 text

Open source contributors? Like i mentioned, we are build simple “laravel admin panel“, and feel free to give us review or PR is just fine, everyone like PR :) We have 59 stars and laravel news mention us in their post few times ;P Repo: https://github.com/systeminc/laravel-admin Hacky?

Slide 62

Slide 62 text

Materials Introduce Stored procedures Jonathan Reinink Docs

Slide 63

Slide 63 text

Questions? Leave review: https://joind.in/user/maki10 Slides: https://speakerdeck.com/maki10 Twitter: https://twitter.com/NemanjaMaki10