Queries avanzadas en Salesforce (Parte 2)

Salesforce Jedi
7 min readJun 6, 2023

--

Está es la continuación de este artículo: Queries Avanzadas en Salesforce (Parte 1)

Primero, el disclaimer obligatorio. Si has entrado en este artículo entiendo que ya sabes hacer queries sencillas en Salesforce. Si no es así, igual la lectura se te hace algo pesada porque vamos a hablar de opciones más avanzadas a la hora de consultar datos en Salesforce. Si no cuentas con la base para hacer consultas sencillas en Salesforce te recomiendo que adquieras esa base antes y dejes este artículo para más adelante.

1 Hay filtros mejores que otros

En la primera parte de esta serie de artículos hemos aprendido que siempre va a ser más eficiente una query cuando más la filtremos, pero esto tiene excepciones y necesitamos profundizar un poco más para entender que filtros priorizar sobre otros.

Cuando aplicamos filtros en la cláusula WHERE, unos filtros se evalúan más rápidos que otros en la base de datos. Cómo esto es un artículo sobre hacer queries en Salesforce, no entraré en detalle de porque unos son más eficientes que otros. Me limitaré a dar una lista de los que son más eficientes y tendrás que creerme.

El consejo es simple, evitar filtros con operadores negativos. Operadores cómo “!=” o “NOT LIKE”, funcionan peor que sus contrapartes “=” o “LIKE”.

Vamos a ver un ejemplo de cómo NO hay que hacerlo:

SELECT Name, Rating
FROM Account
WHERE Rating != 'Cold'

Ahora veamos un ejemplo de cómo SI hay que hacerlo:

SELECT Name, Rating
FROM Account
WHERE Rating IN ('Hot', 'Warm')

Puede parecer contradictorio, porque estamos incluyendo más valores en el filtro de Rating, pero la segunda consulta será más eficiente que la primera.

También tenemos que evitar los filtros con “wildcards” y el operador “LIKE”, siempre hay que intentar ser lo más preciso posible. Y si tenemos que evitar el operador “LIKE”, aún más tenemos que evitar el operador “NOT LIKE” al ser su contraparte negativa.

2 Índices

Otra de las cosas que tenemos que tener en cuenta para optimizar los filtros en nuestras queries es el campo sobre el que realizamos el filtro. Hay dos tipos de campos en este aspecto, los indexados y los no indexados. Filtrar por un campo indexado siempre nos va a dar mejor rendimiento que filtrar por un campo no indexado.

Un campo indexado se almacena en la base de datos de tal manera que luego podamos recuperarlos rápidamente. Hay campos en Salesforce que se indexarán automáticamente, ya sea porque son estándar y comportarse de esa manera por definición de Salesforce, cómo para campos personalizados según sus características.

Esta es la lista completa de los campos estándar de Salesforce (presentes en todos los objetos) que se indexan en la base de datos:

  • Id
  • Name
  • OwnerId
  • CreatedDate
  • SystemModstamp
  • RecordTypeId

De la misma manera, todos estos tipos de campos personalizados se indexarán automáticamente:

  • Lookup
  • Master-Detail
  • Cualquier campo marcado como único
  • Cualquier campo marcado como id externo

Aunque con Salesforce siempre hay excepciones. Si tienes un campo que cumple con las características anteriores puedes hablar con Salesforce para ver si puedes ellos desde soporte indexar el campo. Lo único que te pedirán son cosas lógicas cómo que el campo no pueda tener un valor nulo en ningún registro.

Ya sabes, si quieres optimizar tus queries, utiliza filtros sobre filtros indexados.

3 Skinny Table

Pongamos en situación. Tienes un objeto en el que tienes muchísimos registros, 2 millones, por ejemplo. Cuando intentas hacer consultas sobre ese objeto y, tras revisar el punto anterior para optimizar tus filtros, sigues sin conseguir el rendimiento que quieres es hora de que entren en acción las Skinny Tables.

El funcionamiento de estas Skinny Table es muy sencillo. Guardar en una tabla a parte exclusivamente los datos que necesitemos traernos en nuestra consulta para reducir la carga de la base de datos. No sólo la podemos utilizar en SOQL, también nos sirve para optimizar los tiempos de carga en Reports o List Views.

Parece muy bonito, pero tiene sus limitaciones. No podemos crearla sobre todos los objetos estándar, sólo podremos crear Skinny Tables sobre Account, Contact, Opportunity, Lead y Case. Aunque podremos crearlas sobre cualquier objeto estándar. Hay algunos tipos de campos que no están permitidos en este tipo de tablas (cómo las fórmulas), pero nada que no puedas solucionar moviendo esos datos a otro campo.

Nuevamente, como en el paso anterior con los índices personalizados, tendremos que ponernos en contacto con el soporte de Salesforce para que creen la Skinny Table para nosotros. Nos pedirán cosas lógicas cómo que hayamos probado primero a optimizar nuestra query, ve con los deberes hecho y ahorrarás tiempo.

Con este consejo (y algo de ayuda del soporte de Salesforce) no volverás a tender problemas de rendimiento con tus queries.

4 Big Objects

Este es otro tipo de tablas que podemos crear en Salesforce, pero esta vez somos independiente, no necesitamos al soporte de Salesforce para que nos cree nuestras tablas. El caso de uso de los Big Objects está claro, guardar un histórico de tus datos.

Si estás teniendo problemas de rendimiento con una consulta y crees por la cantidad de registros en ese objeto, lo que podrías hacer es crear un Big Object para guardar los registros más antiguos de ese objeto y así aligerar el número de registros en el objeto tradicional.

La gestión de históricos de tus objetos no es decisión únicamente técnica. Deben participar gente de negocio para hacer la gestión correcta de cada histórica en base a la naturaleza de cada dato. Por ejemplo, hay muchos países que exigen que toda la información fiscal y contable de una empresa se conserven una serie de años. De la misma manera puede pasar con datos de usuarios. Si hiciéramos una gestión indebida del histórico de nuestros datos poder incurrir en un delito.

Al igual que las Skinny Table, son tablas de sólo lectura y tienen sus propios límites a la hora de consultarlas. Mi recomendación es que las utilices como un contenedor de datos que te gustaría guardar, pero no vas a estar consultando en tus procesos de negocio. Para guardar esos datos que sólo vas a utilizar para hacer un informe al año, por ejemplo.

5 Diseño de visibilidad

Hay una manera con la que podrías mantener una gran cantidad de registros en un objeto y a la vez mejorar el rendimiento de tus consultas para todos los usuarios de tu aplicación. En realidad, es algo obvio, pero que muchas veces no tenemos en cuenta a la hora de medir el rendimiento de nuestras consultas.

El objetivo de este paso es limitar al máximo la cantidad de registros que ve determinado usuario para así reducir la carga que pueda tener la base de datos al intentar leer determinada tabla con ese usuario. La visibilidad de los registros para cada usuario está indexada en Salesforce, por lo que muchas veces será más eficiente quitarle visibilidad sobre un registro que añadir un filtro para excluirlo de nuestra consulta.

Podemos diseñar la visibilidad de los registros de nuestra aplicación de múltiples maneras. Salesforce pone a nuestra disposición roles, OWD, Sharing Rules, Restriction Rules, y otra serie de funcionalidad para que adaptemos nuestra aplicación a cualquier requisito.

En el único caso que este truco no funcionaría es que el usuario que tiene que ejecutar la consulta tenga que tener visibilidad sobre todos los registros del objeto. Aunque en ese caso sería motivo de revisión de nuestro diseño de visibilidad, o de nuestra gestión de históricos.

6 External Objects

Puede que la solución a tus problemas es simplemente no utilizar la base de datos de Salesforce. Los External Objects nos permiten trabajar con una base de datos fuera de Salesforce, y utilizar Salesforce como la interfaz para interactuar con esa base de datos.

Este mecanismo usa un estándar llamado oData, que le permiten a Salesforce y como al otro sistema (donde tienes tu base de datos) hablar el mismo idioma. Así cuando Salesforce vaya a consultar datos a esa tabla, el otro sistema sepa cómo responderle.

En este caso estaríamos limitados a la capacidad del sistema donde alojemos nuestra base de datos y a las propias de la comunicación HTTP con la que interactúan ambos sistemas. El optimizar la base de datos ahora recaería en nuestros hombros. También tendríamos que hacer el desarrollo de una API siguiendo el estándar oData que haga de intermediario entre nuestra base de datos y Salesforce.

Parece la solución a todos tus problemas, aunque como siempre en Salesforce, tiene sus limitaciones. Nuestras consultas podrán funcionar perfecto, pero hay mucha funcionalidad estándar de Salesforce que no podrás utilizar. Y no son funcionalidades triviales, son funcionalidades esenciales para mí. Por ejemplo, no podremos crear Sharing Rules para poder aprovechar el consejo anterior, o algo tan simple como crear una formula.

Yo tras haberlos implementado en varios proyectos, no los recomendaría. Dan más problemas, debido a sus limitaciones dentro de Salesforce, que soluciones. A esto se le suma el precio de la licencia de “Salesforce Connect” que hay que contratar para poder trabajar con este tipo de objectos.

Hemos obviado muchas opciones que ofrecen las consultas SOQL por ser más básicas y ser generales en casi todos los motores de base de datos. Sólo hemos incluido cosas muy particulares de Salesforce y su base de datos, funcionalidades que uno no suele utilizar en el día a día, pero conocerlas nos puede solucionar un problema imprevisto. Estoy preparando una tercera parte, sígueme para más artículos técnicos de Salesforce.

Y recuerda joven padawan:

--

--

Salesforce Jedi

+7 years in Salesforce landscape, now as architect and tech lead. Take a look to our GitHub repo: https://github.com/sfdcjedi