General best practices
To query data using Data Query, Zuora recommends the following best practices.
Familiarize yourself with the business objects
Zuora recommends that you use the following statement to get familiar with Zuora objects and object schemas before you start using Data Query to retrieve data.
SHOW TABLES
SHOW COLUMNS FROM|IN {table}
DESCRIBE {table}
DESC {table}
SQL Dialect
Zuora’s Data Query engine is powered by Trino. For advanced syntax and knowledge, refer to the Trino documentation here.
Query help on other sites, such as StackOverflow, might not be compatible with Trino. For example, postgres offers nuanced syntax compared to Trino.
Reference all new variables with a table and variable declaration
Recommended | Not recommended |
---|---|
|
|
Use JOINs effectively - Table order
1 SELECT *
2 FROM smaller_left_table
3 INNER JOIN bigger_right_table ON smaller_left_table.bigger_right_id = bigger_right_table.id
Recommended | Not recommended |
---|---|
|
|
Use JOINs effectively - Index JOIN
Enable Index Join for data sets that you can narrow down with unique identifiers.
Index Join is an addition to LEFT, RIGHT, OUTER, and/or INNER JOINs and can be enabled whenever a JOIN is used. Index join is a useful addition to other joins when you have a specific reference value in your WHERE clause to index another large table by.
For example, you want to get Account and Subscription information tied to a specific ProductRatePlanCharge. The ProductRatePlanCharge table is one of the largest tables in your query. However, you only need the ProductRatePlanCharge that matches the specific ID in your WHERE clause. You can use the Index Join in your query as follows:
1 SELECT Account.AccountNumber, Subscription.Name
2 FROM ProductRatePlanCharge PRPC
3 JOIN RatePlanCharge RPC ON PRPC.id = RPC.productrateplanchargeid
4 JOIN RatePlan RP ON RP.id = RPC.rateplanid
5 JOIN Subscription ON Sub.id = RP.subscriptionid
6 JOIN Account ON Account.id = Subscription.accountid
7 WHERE PRPC.id = '1375'
Note that when using Index Join, the field used in your WHERE clause must be found in the table that you are indexing (the table in your FROM statement). This field should narrow down the set of records returned from the indexed-table to be less than the query processing limit . In this example, ProductRatePlanCharge table will be indexed by the id
, which is 1375
, to narrow down the ProductRatePlanCharges that the query JOINs with RatePlanCharges.
Index Join does not apply to non-indexed fields. When utilizing non-indexed fields in the WHERE clause, all table rows are considered input records, which can raise the chances of reaching the query processing limit. For more information about indexed fields of Zuora objects, see Indexed fields .
You can use Index Join through the following ways:
-
Make a Submit data query API call with
useIndexJoin
set totrue
in the request body. -
Tick the Use index join checkbox on Retrieve: Data Query Workflow task UI.
In general, it is safe to use and helpful when you have a lot of data to scan, although sometimes you might experience problems for certain object types, usually in the case where data does not fit the format expected for the join.
Use LIMIT to sample your query results
Before your first time running a full query, Zuora recommends that you add LIMIT statement to get a quick snapshot of the first few entries. See the syntax below.
1 SELECT balance, accountId, invoiceDate
2 FROM Invoice
3 WHERE accountId = '123-456-7890' AND balance > 0
4 ORDER BY invoiceDate
5 DESC LIMIT 1
Once you ensure the result is desirable and meaningful, you can run the full query.
Note that the LIMIT function only affects the output records limitation.
Filter efficiently
Define clear date ranges
Recommended | Not recommended |
---|---|
|
|
Avoid using six digits of second precision for timestamp fields
Recommended | Not recommended |
---|---|
|
|
Separate a large query into smaller ones
Date range | Separated query |
---|---|
January - March |
|
April - June |
|
July - Aug |
|
Use exact strings instead of strings containing a wildcard
Recommended | Not recommended |
---|---|
|
|
|
|
A custom picklist field can be created with the exact values and then leveraged by the query in addition to the free text field. For example:
Original field ProductName__c | New additional custom field ProductCategory__c |
---|---|
Annual SiliDog Basic | SiliDog |
Annual SiliDog Premium | SiliDog |
Monthly SiliDog Basic | SiliDog |
ArctiCat Basic | ArctiCat |
Original clause: where ProductName__c LIKE '%SiliDog%'
Updated clause: where ProductCategory__c = 'SiliDog'
Avoid using NULL in your filter
The following filter is NOT recommended.
1 SELECT rpct.includedunits
2 FROM Rateplanchargetier rpct
3 WHERE rpct.discountamount IS NULL
4 AND rpct.discountpercentage IS NULL
Avoid using functions on the left-hand side of the comparison operator
Recommended | Not recommended |
---|---|
|
|
Filter on fields with subsets of unique values
Zuora business object | Fields with subsets of unique values |
---|---|
RatePlanCharge |
|
RatePlanChargeTier |
|
InvoiceItem |
|
TaxationItem |
|
JournalEntry |
|
Usage |
|
Avoid using LIKE filters
LIKE filters will not be pushed down for optimization and they usually decrease the query performance. The following example is NOT recommended.
SELECT SourceType FROM usage WHERE Id LIKE '8a28b7f57cc19b8d017cc352976b7%'