Data Design Tips for Developing
Robust Apps on Force.com
Lessons learned while developing a finance system on
Force.com
St...
Safe harbor
Safe harbor statement under the Private Securities Litigation Reform Act of 1995:
This presentation may contai...
Steven Lawrance
Lead Member of the Technical Staff
Session Agenda
▪ Designing within limits
▪ Handing updates to arbitrary numbers of records
▪ Demonstration
▪ Executing agg...
Designing within limits
▪ Design decisions should consider resource availability
• Custom object limit
• Custom tab limit
...
Designing within limits
Designing within limits
▪ Scarce
• Record storage

▪ Plentiful
• Custom objects
• Tabs
• Apex code lines

▪ Selection of l...
Designing within limits
Ne
w

Reconciliation
1

∞

Opportunity
(Donation)

∞

Primary
Campaign

1

Campaign
∞

1

Default
...
Handing updates to arbitrary numbers of records
@future, Maps, and Visualforce are your friends.
▪ @future method: Asynchr...
Handing updates to arbitrary numbers of records
Visualforce page sends groups of batches to the @future method
▪ Page chec...
Handing updates to arbitrary numbers of records
Processing within @future

Input from Visualforce
Key

Value

For each key...
Demonstration
Executing aggregate queries with limits and offsets
▪ Aggregations can return at most 500 rows per query.
▪ By using LIMIT...
Executing aggregate queries with limits and offsets
for (Integer batchOffset = 0; batchOffset < 2000;) {
Integer aggregate...
Executing aggregate queries with limits and offsets
Break apart disjunctions into separate queries if it’s faster.
▪ If yo...
Executing aggregate queries with limits and offsets
▪ The query plan in the underlying database is much more efficient whe...
Executing aggregate queries with limits and offsets
▪ Index range scans are faster than table scans.
▪ Use of ‘OR’ can lea...
Sorting complex objects
▪ Before Winter ‘14, using a Map<String,ComplexObject> and a
List<String> to call List.sort() was ...
Steven Lawrance
Lead Member of the
Technical Staff
Data Design Tips for Developing Robust Apps on Force.com
Upcoming SlideShare
Loading in …5
×

Data Design Tips for Developing Robust Apps on Force.com

238 views
175 views

Published on

Optimization is important when working with large amounts of data. Optimization is especially important when building an app in a multi-tenant platform where you have governor limits. Join us for lessons learned while developing a finance system on Force.com. We'll cover topics like executing aggregate queries with limits and offsets, handing updates to arbitrary numbers of records, and sorting complex objects.

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
238
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Data Design Tips for Developing Robust Apps on Force.com

  1. 1. Data Design Tips for Developing Robust Apps on Force.com Lessons learned while developing a finance system on Force.com Steven Lawrance, Salesforce.com, Lead Member of the Technical Staff
  2. 2. Safe harbor Safe harbor statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward-looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services. The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of any litigation, risks associated with completed and any possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-K for the most recent fiscal year and in our quarterly report on Form 10-Q for the most recent fiscal quarter. These documents and others containing important disclosures are available on the SEC Filings section of the Investor Information section of our Web site. Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
  3. 3. Steven Lawrance Lead Member of the Technical Staff
  4. 4. Session Agenda ▪ Designing within limits ▪ Handing updates to arbitrary numbers of records ▪ Demonstration ▪ Executing aggregate queries with limits and offsets ▪ Sorting complex objects ▪ Q&A
  5. 5. Designing within limits ▪ Design decisions should consider resource availability • Custom object limit • Custom tab limit • Storage limits • API call limits
  6. 6. Designing within limits
  7. 7. Designing within limits ▪ Scarce • Record storage ▪ Plentiful • Custom objects • Tabs • Apex code lines ▪ Selection of limits to optimize • Record storage limits were selected for optimization in this project. • Runtime computation was favored over temporary storage in a custom object.
  8. 8. Designing within limits Ne w Reconciliation 1 ∞ Opportunity (Donation) ∞ Primary Campaign 1 Campaign ∞ 1 Default Designation ∞ 1 ∞ 1 Finance Batch Donation Designation ∞ 1 Designation
  9. 9. Handing updates to arbitrary numbers of records @future, Maps, and Visualforce are your friends. ▪ @future method: Asynchronously update batches of records. • Update only up to the DML execution and record limits. ▪ Maps: Identify batches in the keys and changes in the values. • @future private static void runLater(Map<String,String> batchUpdateValues) ▪ Visualforce: Use to re-invoke the next @future method call, if needed. • @future methods cannot be called from a @future method.
  10. 10. Handing updates to arbitrary numbers of records Visualforce page sends groups of batches to the @future method ▪ Page checks the donation update status during the page load. • Updates required: Call the @future method and reload the page every 4 seconds. • Updates in progress: Reload the page every 4 seconds. • Complete: Display the regular user interface. ▪ The @future method updates donations until it gets to the DML limits. • Set the donation update status at the end of @future method.
  11. 11. Handing updates to arbitrary numbers of records Processing within @future Input from Visualforce Key Value For each key, update each donation to the target value Credit Card AmEx 2013-11-02 Finance Batch a0nK0000000FAY 8 Credit Card AmEx 2013-11-02 Fred Smith AmEx 2013-11-02 $5.00 Finance Batch a0nK0000000FAY8 Alex Jones AmEx 2013-11-02 $10.00 Finance Batch a0nK0000000FAY8 Check 2013-11-02 B123456 . . . Finance Batch a0nK0000000FAY 9 . . . . . . Catherine Katz AmEx 2013-11-02 $10.00 . . .
  12. 12. Demonstration
  13. 13. Executing aggregate queries with limits and offsets ▪ Aggregations can return at most 500 rows per query. ▪ By using LIMIT and OFFSET, it’s possible to query more than 500 aggregated rows. ▪ In an aggregate query, the OFFSET can’t be 2000 or higher.
  14. 14. Executing aggregate queries with limits and offsets for (Integer batchOffset = 0; batchOffset < 2000;) { Integer aggregateBatchCount = 0, aggregateBatchSize = 500; for (AggregateResult donationBatch : [SELECT … FROM … WHERE … GROUP BY … ORDER BY … NULLS FIRST LIMIT :aggregateBatchSize OFFSET :batchOffset]) { aggregateBatchCount++; … } if (aggregateBatchCount < aggregateBatchSize) { break; } else { batchOffset += aggregateBatchCount; } }
  15. 15. Executing aggregate queries with limits and offsets Break apart disjunctions into separate queries if it’s faster. ▪ If your query takes too long to execute and makes use of ‘OR’, then try splitting it into multiple queries that don’t use ‘OR’ SELECT … FROM Donation_Designation__c WHERE Donation__r.CloseDate >= :startDate AND Donation__r.CloseDate < :endDatePlusOne AND (Donation__r.Fin_Batch__r.Rec__c = :recId OR Donation__r.Batch__c = NULL OR Donation__r.Batch__r.Status__c = 'Committed') GROUP BY … ORDER BY … LIMIT … OFFSET …
  16. 16. Executing aggregate queries with limits and offsets ▪ The query plan in the underlying database is much more efficient when all filters are conjunctive (joined with ‘AND’). SELECT … FROM Donation_Designation__c WHERE Donation__r.CloseDate >= :startDate AND Donation__r.CloseDate < :endDatePlusOne AND Donation__r.Fin_Batch__r.Rec__c = :recId GROUP BY … ORDER BY … LIMIT … OFFSET …
  17. 17. Executing aggregate queries with limits and offsets ▪ Index range scans are faster than table scans. ▪ Use of ‘OR’ can lead to table scans. ▪ Salesforce.com can create an index for frequently filtered fields.
  18. 18. Sorting complex objects ▪ Before Winter ‘14, using a Map<String,ComplexObject> and a List<String> to call List.sort() was a way to sort without running out of script statements. The properties exist in the String key in the order to sort by. ▪ In Winter ’14 and beyond, the recommended approach is to implement the Comparable interface and call List.sort() on a List of your object. • public class ComplexObject implements Comparable { … public Integer compareTo(Object compareTo) { /* implementation here */ } }
  19. 19. Steven Lawrance Lead Member of the Technical Staff

×