Ajax World2008 Eric Farrar
-
Upload
rajivmordani -
Category
Technology
-
view
258 -
download
0
Transcript of Ajax World2008 Eric Farrar
![Page 1: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/1.jpg)
10101010101010001010101101101010101011
It’s 11 p.m., Do you know where you queriesare?Eric Farrar, Sybase iAnywhere
![Page 2: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/2.jpg)
Outline
What are ORMs and Active Records? Tradeoffs
Playing Nice with your Database Managing Indexes Eager Loading and Client-Side Joins Lazy Loading
Conclusion
![Page 3: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/3.jpg)
Object-Relational Mapper
Systems to bridge the gap between object-oriented languagesand relational databases
Inherently difficult: Normalization (splitting data across tables) Databases can only store scalar values Add an extra layer of abstraction
class Employee < ActiveRecord::Base belongs_to :officeend
class Office < ActiveRecord::Base has_one :employeeend
![Page 4: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/4.jpg)
Active Record Pattern
The ‘meat’ of an ORM that handles the CRUD work Allows regular objects to be treated as persistent objects Ideally, totally abstracts all database interaction
my_office = Office.new()
my_office.number = 123
me = Employee.new
me.name = ‘Eric Farrar’
me.office = my_office
![Page 5: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/5.jpg)
Examples of ORMs/Active Records
LINQ (Language Integrated Query) Hibernate / NHibernate Django Ruby on Rails (ActiveRecord) Many more…
For our purposes, we will use Rail’s ActiveRecord for theexamples
![Page 6: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/6.jpg)
Trade-offs
Advantages Easy to learn Simplifies database creation and management No context switching between languages You don’t need know about the database
Disadvantages Performance suffers (up to 50% slower) Often uses lowest-common denominator solution Concurrency semantics often very difficult You don’t need know about the database
![Page 7: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/7.jpg)
Managing Indexes
Indexes are used to make things quick to look up phone book vs. reverse look-up
Indexes should be present on anything you will search for Searching for non-indexed properties will result in full table
scan By default, indexes are usually only put on primary keys Lack of indexes often will not appear during development Result will be a gradual slowdown (as data volume increases)
as opposed to avalanche failure Why not put an index on everything? Multi-column indexes vs. single column indexes
![Page 8: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/8.jpg)
Client-Side Join
Objects are usually ‘related’ to each other belongs_to has_one has_many has_and_belongs_to_many
ORMs use these relationship to allow object traversal ex. me.office
Assuming 10000 employees, how many queries will this codeproduce?Employees.find(:all).each do |e|
puts e.office.number
end
![Page 9: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/9.jpg)
“Man, this is heavy!”
Answer: 10001
Why? The application is doing the work of joining the data, notthe database. This is called a ‘client-side’ join
This is solved by giving a hint to the ORM and the databasethat you intend to use the ‘office’ property
This pattern is called eager loading
Employees.find(:all).each do |e| # <-- 1 query here
puts e.office.number # <-- 10,000 queries here
end
Employees.find(:all :include => :office).each do |e|
puts e.office.number
end
![Page 10: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/10.jpg)
Inviting the Database to the Party
Eager loading solves the N+1 problem, but it is still only halfway there
In ORMs, the relations are defined inside the object models The ORM may know that Employees are Offices are related,
but the database doesn’t know that The database will obediently execute the query, but don’t
expect it to do anything clever Modern query optimizers will use every statistic available when
determining query paths Keeping them ignorant will result in bare-bones optimization
![Page 11: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/11.jpg)
Lazy Loading
Eager loading deals with the case where you want more thanyour class includes
What if you want less? Suppose your Employee class includes a picture field that is a
high resolution bitmap (~ 3 mb) The previous query will actually return the picture in order to fully
populate the object
This innocent code will naively return > 30 Gb of data
Employees.find(:all).each do |e|
puts e.name
end
![Page 12: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/12.jpg)
Be Lazy
Instead, lazily load your object properties
Accessing e.picture will work by issuing another databasequery
This simple example ignores potential problems withconcurrency Use locking
Employees.find(:all :select => [“name”]).each do |e|
puts e.name
end
![Page 13: Ajax World2008 Eric Farrar](https://reader036.fdocuments.in/reader036/viewer/2022081403/5560bae5d8b42afe3b8b4eec/html5/thumbnails/13.jpg)
Conclusions
ORMs and Active Records can provide large productivityadvantages, typically at the expense of performance
ORMs should never be seen as an alternative to learningabout databases (although it can be a good introduction)
At times, you will likely need to drop down to the databaselevel (profiling, etc) to diagnose problems
Ideally, a programmer using a ORM will always consider howtheir code will actually look once it hits the database Similarities to a C compiler
You should be able to answer “Yes!” to the question, “Do youknow where your queries are?”