SOQL | SOSL |
---|---|
Uses query() call on Database | Uses search() on Search Indexes |
Use: when we know which sObjects and Fields the data resides | Use: when we don't know which sObjects and Fields the data risides and want to find it in the most efficient way possible |
Want to:
|
Want to:
|
|
|
String status = 'Active';
if (status != null) {
Account[] accounts = [ SELECT Name
FROM Account
WHERE status__c = :status
];
System.Debug('Count: ' + accounts.size());
}
else {
// full tablescan is avoided
System.Debug('Not Found');
}
vs
// if status is null, result in full tablescan
String status = null;
Account[] accounts = [ SELECT Name
FROM Account
WHERE status__c = :status ];
System.Debug('Count: ' + accounts.size());
Generates most-efficient query based on:
Status__c != 'Active'
tablescan will be used here.
Instead use: Status__c IN ('Open', 'In-Progress')
To find out using an index is efficient ?
To find out using an index is efficient ?
/query?explain=SELECT name,stageName FROM Opportunity WHERE stageName IN ('Closed Won', 'Value Proposition')
{
"plans": [
{
"cardinality": 7, // Estimated #records that leading op type will return
"fields": [],
"leadingOperationType": "TableScan", // primary op type that QO will use to optimize this query
"notes": [ // clues why optimizer can't use this filter
{
"description": "Not considering filter for optimization because unindexed",
"fields": [
"IsDeleted"
],
"tableEnumOrId": "Opportunity"
},
{
"description": "Not considering filter for optimization because unindexed",
"fields": [
"StageName"
],
"tableEnumOrId": "Opportunity"
}
],
"relativeCost": 1.2833333333333334,
// cost is based on the Statistics SF gathered
// plan with lowest cost will be used
// relative cost compared to QO's Selectivity threshold
// > 1 means this query would be selective! TableScan will be used!
// if more than one filter is selective - QO will pick the one with lowest
// cost to drive the query
"sobjectCardinality": 33, // approx. record count for this query
"sobjectType": "Opportunity"
}
],
"sourceQuery": "SELECT name,stageName FROM Opportunity WHERE stageName IN ('Closed Won', 'Value Proposition')"
}
/query?explain=SELECT name,stageName FROM Opportunity WHERE stageName IN ('Closed Won', 'Value Propostion')
AND isDeleted = false
{
"plans": [
{
"cardinality": 3,
"fields": [],
"leadingOperationType": "TableScan",
"notes": [
{
"description": "Not considering filter for optimization because unindexed",
"fields": [
"IsDeleted"
],
"tableEnumOrId": "Opportunity"
},
{
"description": "Not considering filter for optimization because unindexed",
"fields": [
"StageName"
],
"tableEnumOrId": "Opportunity"
},
{
"description": "Not considering filter for optimization because unindexed",
"fields": [
"IsDeleted"
],
"tableEnumOrId": "Opportunity"
}
],
"relativeCost": 0.9944444444444444,
"sobjectCardinality": 33,
"sobjectType": "Opportunity"
}
],
"sourceQuery": "SELECT name,stageName FROM Opportunity WHERE stageName IN ('Closed Won', 'Value Propostion') AND isDeleted = false"
}
Save the important Queries and find out the Query Plan on a regular basis