The CreatorCon Call for Content is officially open! Get started here.

Raw SQL Commands to GlideRecord

stopping
Giga Contributor

I'm running into some performance issues using GlideRecord and GlideAggregate to perform the equivalent of a relatively simple SQL query. The specific problem I'm trying to solve is to determine which reports haven't been run in a certain amount of time (such as a year). My solution which utilizes a GlideAggregate can return the required data, but for scanning through an entire year's worth of report views requires about 30 minutes. When I use the gs.sql() command to perform a simple table join and filter, it takes 13 seconds. Unfortunately, I haven't been able to find a way to actually return any data from the SQL query (since it just posts the result in the Background Script screen). I'm not getting the performance I need out of the GlideAggregate object since it's not taking advantage of SQL's functionality, instead offloading a lot of the work into my Javascript code. Any suggestions would be appreciated! I would prefer to go the SQL route if there's some way to actually get data out of it.

 

GlideAggregate Code (this returns all reports which have been used within x days):

 

function usedReports(days) {

      var used = [];

      var lastRun = new GlideAggregate('report_view');

      lastRun.addAggregate('MAX', 'viewed');

      lastRun.groupBy('report');

      lastRun.addQuery('viewed','>',gs.daysAgo(days));

      lastRun.query();

      while(lastRun.next()) {

              used.push(lastRun.report.sys_id);

      }

      return used;

}

 

SQL Code (this shows all reports which haven't been run within x days):

 

function unusedReports(days) {

      var date = gs.daysAgo(days);

      gs.sql('SELECT A.title FROM sys_report A LEFT JOIN (SELECT * FROM report_view WHERE viewed>\'' + date + '\') B ON A.sys_id=B.report WHERE B.viewed IS NULL ORDER BY A.title;');

}

1 ACCEPTED SOLUTION

tltoulson
Kilo Sage

Have you considered putting a Business Rule on the report_view table?   That way, on every update you can store the most recent value either on a custom field on the Reports table or in a custom table.   This will cache your results and make your query near instantaneous by offloading the work to the business rule.



Edit:   Another alternative to this is a scheduled job run daily that runs smaller incremental queries (reports viewed yesterday) to update the field or cache table.   This could be a nice balance between slamming the db with updates via business rule and a 30 minute query on a massive table.


View solution in original post

2 REPLIES 2

tltoulson
Kilo Sage

Have you considered putting a Business Rule on the report_view table?   That way, on every update you can store the most recent value either on a custom field on the Reports table or in a custom table.   This will cache your results and make your query near instantaneous by offloading the work to the business rule.



Edit:   Another alternative to this is a scheduled job run daily that runs smaller incremental queries (reports viewed yesterday) to update the field or cache table.   This could be a nice balance between slamming the db with updates via business rule and a 30 minute query on a massive table.


That could work, with a bit of pre-processing to deal with all of the pre-existing report_view data (a table which contains nearly 30 million records). I could probably toss that into a script and run it as a one-time thing. I figure this'll be my best option since it doesn't rely on any weird workarounds. I'll let you know how it goes!