- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
I'm working on a Platform Analytics Dashboard where I need to create Count Widgets with interactive filters. The challenge is that the filter values are not fields on the required table (sn_slm_case) in my case. They originate from a catalog variable captured through a Record producer. To expose this values for the reporting, I've decided to use Database View that joins the
- sn_slm_case
- question_answer (to retrieve the variable)
- cmn_cost_center (to get the required fields in this table).
This approach seems to satisfy the reporting requirement but I have concerns regarding scalability. I have come across discussions mentioning the 10,000 record limit for the Database Views with the system property (glide.db.max_view_records) but I haven't found this property in my instance, it seems to be more about the Glide Record queries but still this pops up every time I try to look out the feasibility of this approach.
If a dashboard is built on a Database view and the underlying dataset grows to 50,000+ records, will the dashboard continue to function correctly or will there be any hard platform limitations on using Database View as dashboard sources rather than building a custom field.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi @sinhashivam ,
Yes, you can use a Database View as the source for Platform Analytics dashboards, and 50,000+ rows is not by itself a hard platform limitation.
The important clarification is around:
glide.db.max_view_records
The default value is 10,000, but this property applies only when a Database View is queried through GlideRecord in a script.
It does NOT apply when the Database View is used in:
- Reports
- Lists
- Platform Analytics data visualizations
Reports and visualizations can query all applicable rows from the Database View.
Therefore, you do not need to create or increase glide.db.max_view_records for this dashboard requirement.
However, the bigger concern in your design is performance and row multiplication.
Your proposed view is:
sn_slm_case
-> question_answer
-> cmn_cost_center
This can work, but question_answer can become a very large table, and one Case can have multiple question_answer records.
If you simply join:
sn_slm_case
-> question_answer
without restricting the question, one Case could appear multiple times in the Database View.
For example:
CASE001
Variable A
Variable B
Variable C
could produce three Database View rows for the same Case.
A Count visualization could then return 3 instead of 1.
Recommended Database View design:
1. Start with:
sn_slm_case
2. Join question_answer using both the record relationship and the specific variable.
Conceptually:
case_sys_id = question_answer.table_sys_id
AND
question_answer.question = <SYS_ID_OF_REQUIRED_VARIABLE>
Also restrict the target table where applicable:
question_answer.table_name = sn_slm_case
This ensures that only the answer for the required variable participates in the join.
3. If the variable is a Reference to Cost Center, join its answer value to:
cmn_cost_center.sys_id
Conceptually:
question_answer.value = cmn_cost_center.sys_id
4. Use Left Join where cases without that variable value must still remain visible in the dashboard.
5. Include only fields actually required for reporting.
6. Make sure the Database View Where clauses use indexed fields wherever possible.
ServiceNow specifically recommends indexed fields for Database View joins because performance degradation increases as both the number of joined tables and the size of those tables increase.
Important:
50,000 final Case records may not be a problem.
What matters more is the underlying query.
For example:
50,000 sn_slm_case records
+
5,000,000 question_answer records
+
an inefficient join
can perform poorly even though the dashboard ultimately displays only one Count.
Also be careful if you add multiple variables to the same Database View.
For example, do not join one generic question_answer alias for Variable A, Variable B, and Variable C.
Use separate aliases:
qa_cost_center
qa_region
qa_business_unit
and restrict each alias to one specific question.
Otherwise you can create Cartesian-style row multiplication and incorrect counts.
For Interactive Filters:
Database Views are supported.
If your interactive filter originates from another table, configure the appropriate Interactive Filter Reference or enable the option to apply the filter to Database Views.
So technically this architecture is supported.
However, for a production dashboard, I would first ask whether this catalog variable is an important business/reporting attribute.
If Cost Center is regularly required for:
- Dashboards
- Filtering
- Reporting
- Assignment
- Automation
- Integrations
- Security
- Analytics
then I would not keep it only as a catalog variable.
The better data model is:
Record Producer variable
-> Map to a proper reference field on sn_slm_case
-> cmn_cost_center
Then your dashboard can report directly on:
sn_slm_case.u_cost_center
without joining question_answer every time the dashboard loads.
If the Record Producer variable supports Map to field, use that OOB capability rather than creating scripting just to copy the value.
Recommended decision:
Occasional reporting requirement
-> Database View is acceptable
Frequently used enterprise reporting/filter dimension
-> Store/map the value on sn_slm_case
For your specific case, if this dashboard will be heavily used and the dataset will continue growing, I would recommend storing Cost Center on the Case itself.
That gives you:
- Better query performance
- Simpler Interactive Filters
- Correct Case counts
- Easier reporting
- Easier indexing
- Less dependency on question_answer
- Better long-term maintainability
If you continue with the Database View, test it using realistic production volumes and verify:
- Query execution time
- Dashboard load time
- Interactive filter response time
- Correct Count values
- Cases without variable answers
- ACL behavior
- Duplicate Case rows
You can test the view using:
System Definition > Database Views
-> Open the view
-> Try It
In summary:
There is no 10,000-record hard limit for a Platform Analytics report based on a Database View.
glide.db.max_view_records
-> Applies to scripted GlideRecord queries against Database Views
Reports / Platform Analytics
-> Not restricted by that property
Your real scalability concern is the runtime join against question_answer and possible duplicate rows.
For a frequently used reporting dimension such as Cost Center, mapping it to a real Case field is the stronger production architecture.
Official references:
Database Views:
https://www.servicenow.com/docs/r/platform-administration/table-administration-and-data-management/c...
Database View record limit:
https://www.servicenow.com/docs/r/platform-administration/table-administration-and-data-management/c...
Interactive Filters with Database Views:
https://www.servicenow.com/docs/r/now-intelligence/interactive-filters/apply-filter-to-all-tables-in...
Test a Database View:
https://www.servicenow.com/docs/r/platform-administration/table-administration-and-data-management/t...
Hope this helps!
If this response helped, please mark it as Helpful.
If it resolves your issue, please Accept it as Solution.
Kind Regards,
Abhishek Pal
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi @sinhashivam ,
Yes, you can use a Database View as the source for Platform Analytics dashboards, and 50,000+ rows is not by itself a hard platform limitation.
The important clarification is around:
glide.db.max_view_records
The default value is 10,000, but this property applies only when a Database View is queried through GlideRecord in a script.
It does NOT apply when the Database View is used in:
- Reports
- Lists
- Platform Analytics data visualizations
Reports and visualizations can query all applicable rows from the Database View.
Therefore, you do not need to create or increase glide.db.max_view_records for this dashboard requirement.
However, the bigger concern in your design is performance and row multiplication.
Your proposed view is:
sn_slm_case
-> question_answer
-> cmn_cost_center
This can work, but question_answer can become a very large table, and one Case can have multiple question_answer records.
If you simply join:
sn_slm_case
-> question_answer
without restricting the question, one Case could appear multiple times in the Database View.
For example:
CASE001
Variable A
Variable B
Variable C
could produce three Database View rows for the same Case.
A Count visualization could then return 3 instead of 1.
Recommended Database View design:
1. Start with:
sn_slm_case
2. Join question_answer using both the record relationship and the specific variable.
Conceptually:
case_sys_id = question_answer.table_sys_id
AND
question_answer.question = <SYS_ID_OF_REQUIRED_VARIABLE>
Also restrict the target table where applicable:
question_answer.table_name = sn_slm_case
This ensures that only the answer for the required variable participates in the join.
3. If the variable is a Reference to Cost Center, join its answer value to:
cmn_cost_center.sys_id
Conceptually:
question_answer.value = cmn_cost_center.sys_id
4. Use Left Join where cases without that variable value must still remain visible in the dashboard.
5. Include only fields actually required for reporting.
6. Make sure the Database View Where clauses use indexed fields wherever possible.
ServiceNow specifically recommends indexed fields for Database View joins because performance degradation increases as both the number of joined tables and the size of those tables increase.
Important:
50,000 final Case records may not be a problem.
What matters more is the underlying query.
For example:
50,000 sn_slm_case records
+
5,000,000 question_answer records
+
an inefficient join
can perform poorly even though the dashboard ultimately displays only one Count.
Also be careful if you add multiple variables to the same Database View.
For example, do not join one generic question_answer alias for Variable A, Variable B, and Variable C.
Use separate aliases:
qa_cost_center
qa_region
qa_business_unit
and restrict each alias to one specific question.
Otherwise you can create Cartesian-style row multiplication and incorrect counts.
For Interactive Filters:
Database Views are supported.
If your interactive filter originates from another table, configure the appropriate Interactive Filter Reference or enable the option to apply the filter to Database Views.
So technically this architecture is supported.
However, for a production dashboard, I would first ask whether this catalog variable is an important business/reporting attribute.
If Cost Center is regularly required for:
- Dashboards
- Filtering
- Reporting
- Assignment
- Automation
- Integrations
- Security
- Analytics
then I would not keep it only as a catalog variable.
The better data model is:
Record Producer variable
-> Map to a proper reference field on sn_slm_case
-> cmn_cost_center
Then your dashboard can report directly on:
sn_slm_case.u_cost_center
without joining question_answer every time the dashboard loads.
If the Record Producer variable supports Map to field, use that OOB capability rather than creating scripting just to copy the value.
Recommended decision:
Occasional reporting requirement
-> Database View is acceptable
Frequently used enterprise reporting/filter dimension
-> Store/map the value on sn_slm_case
For your specific case, if this dashboard will be heavily used and the dataset will continue growing, I would recommend storing Cost Center on the Case itself.
That gives you:
- Better query performance
- Simpler Interactive Filters
- Correct Case counts
- Easier reporting
- Easier indexing
- Less dependency on question_answer
- Better long-term maintainability
If you continue with the Database View, test it using realistic production volumes and verify:
- Query execution time
- Dashboard load time
- Interactive filter response time
- Correct Count values
- Cases without variable answers
- ACL behavior
- Duplicate Case rows
You can test the view using:
System Definition > Database Views
-> Open the view
-> Try It
In summary:
There is no 10,000-record hard limit for a Platform Analytics report based on a Database View.
glide.db.max_view_records
-> Applies to scripted GlideRecord queries against Database Views
Reports / Platform Analytics
-> Not restricted by that property
Your real scalability concern is the runtime join against question_answer and possible duplicate rows.
For a frequently used reporting dimension such as Cost Center, mapping it to a real Case field is the stronger production architecture.
Official references:
Database Views:
https://www.servicenow.com/docs/r/platform-administration/table-administration-and-data-management/c...
Database View record limit:
https://www.servicenow.com/docs/r/platform-administration/table-administration-and-data-management/c...
Interactive Filters with Database Views:
https://www.servicenow.com/docs/r/now-intelligence/interactive-filters/apply-filter-to-all-tables-in...
Test a Database View:
https://www.servicenow.com/docs/r/platform-administration/table-administration-and-data-management/t...
Hope this helps!
If this response helped, please mark it as Helpful.
If it resolves your issue, please Accept it as Solution.
Kind Regards,
Abhishek Pal