As a general recommendation, design your applications using Appian Records with Data Sync enabled. The Data Sync feature provides the ability to relate and transform data using record relationships and custom record fields, even across multiple data sources. It also caches your source data in Appian and provides the Appian Data Fabric framework to efficiently query data. Keep in mind though that it is still recommended to follow database design best practices when using synced records to store your data. If you still need to use a database view, this play provides a basic introduction to creating views for Appian applications.
One of the primary reasons developers choose to materialize views is performance. Thanks to the Appian Data Fabric, the ability to create complex data structures and related queries is easier and more performant than ever. That said, there are constraints related to the Appian Data Fabric that make it not a good fit for certain use cases. In the event that you need to use the database, rather than synced records and record relationships, then materializing views can improve performance.
Materializing views can be helpful when the requirements for a view result in the need for any of the following:
The best way to determine if Materializing is necessary is to perform Database Volume Testing as early as possible in the development cycle. It is also recommended to review the data model guidance to ensure that your data model is scalable.
When you have a potentially slowly performing view you will want to test all of the following to ensure proper performance in production:
If you find your view is slow you will want to try all of the following before resorting to materializing the view:
When all other avenues have been exhausted the last step is to "materialize" the view. This is in quotations because MySQL does not technically support materialized views. However, the same effect can be achieved by creating a table which stores the same data as the view and is updated each time any of the underlying tables are updated. Note that "materialized" views may not be the best solution if the data in the view is frequently written to the database or if views require real time updates. You will need to test your views after they are materialized to ensure that there is no negative performance impact.
The steps to materialize a MariaDB SQL view are as follows:
IF i_objectId IS NOT NULL THEN DELETE FROM APP_M_V_VIEW WHERE ID_PK IN ( SELECT ID_PK FROM APP_TABLE where IS_ACTIVE<>1 and ID_PK=i_obejctId ); END IF;
IF i_deletedObjectId IS NOT NULL THEN DELETE FROM APP_M_V_OBJECT WHERE ID = i_deletedObjectId; END IF;
DELIMITER $$ CREATE PROCEDURE `APP_UpdateView`(IN `i_childId` INT, IN `i_parentId` INT, IN `i_objectId` INT) NO SQL BEGIN IF ( (i_childId IS NULL OR i_childId = 0) AND (i_parentId IS NULL OR i_parentId = 0) AND (i_objectId IS NULL OR i_objectId = 0) ) THEN TRUNCATE APP_M_V_VIEW; END IF; INSERT INTO APP_M_V_VIEW ( OBJECT_ID_PK, CHILD_ID_FK, OBJECT_TITLE, OBJECT_DESCRIPTION, OBJECT_OWNER, OBJECT_DUE_DATE, IS_INITIATED, CHILD_SHORT_DESCRIPTION, CHILD_COMMITMENT, PARENT_START_DATETIME, PARENT_IDENTIFIER, IS_PARENT_HIDDEN, PARENT_TITLE ) SELECT `obj`.`OBJECT_ID_PK` AS `OBJECT_ID_PK`, `obj`.`CHILD_ID_FK` AS `CHILD_ID_FK`, `obj`.`TITLE` AS `OBJECT_TITLE`, `obj`.`DESCRIPTION` AS `OBJECT_DESCRIPTION`, `obj`.`OWNER` AS `OBJECT_OWNER`, `obj`.`DUE_DATE` AS `OBJECT_DUE_DATE`, ( CASE WHEN(`obj`.`IS_INITIATED` = 1) THEN 'Initiated' ELSE 'Not Initiated' END ) AS `IS_INITIATED`, `ai`.`SHORT_DESCRIPTION` AS `CHILD_SHORT_DESCRIPTION`, `ai`.`COMMITMENT` AS `CHILD_COMMITMENT`, `parent`.`EXPECTED_START_DATETIME` AS `PARENT_START_DATETIME`, `parent`.`OBJECT_NUMBER` AS `PARENT_IDENTIFIER`, `parent`.`IS_HIDDEN` AS `IS_PARENT_HIDDEN`, `parent`.`TITLE` AS `PARENT_TITLE` FROM `Appian`.`APP_OBJECT` `obj` LEFT JOIN `Appian`.`APP_PARENT_CHILD` `ai` ON `ai`.`PARENT_CHILD_ID` = `obj`.`CHILD_ID_FK` LEFT JOIN `Appian`.`APP_PARENT` `parent` ON `parent`.`PARENT_ID_PK` = `ai`.`PARENT_ID_FK` WHERE`obj`.`IS_ACTIVE` = 1) AND(`ai`.`IS_DELETED` <> 1 AND`parent`.`IS_ACTIVE` = 1 AND IF(ISNULL(i_childId) OR i_childId = 0, 1, `obj`.`CHILD_ID_FK`) = IF(ISNULL(i_childId) OR i_childId = 0, 1, i_childId) AND IF(ISNULL(i_parentId) OR i_parentId = 0, 1, `ai`.`PARENT_ID_FK`) = IF(ISNULL(i_parentId) OR i_parentId = 0, 1, i_parentId) AND IF(ISNULL(i_objectId) OR i_objectId = 0, 1, `obj`.`OBJECT_ID_PK`) = IF(ISNULL(i_objectId) OR i_objectId = 0, 1, i_objectId) GROUP BY `obj`.`OBJECT_ID_PK` ON DUPLICATE KEY UPDATE OBJECT_ID_PK= VALUES(OBJECT_ID_PK), CHILD_ID_FK= VALUES(CHILD_ID_FK), OBJECT_TITLE= VALUES(OBJECT_TITLE), OBJECT_DESCRIPTION= VALUES(OBJECT_DESCRIPTION), OBJECT_OWNER= VALUES(OBJECT_OWNER), OBJECT_DUE_DATE= VALUES(OBJECT_DUE_DATE), IS_INITIATED= VALUES(IS_INITIATED), CHILD_SHORT_DESCRIPTION= VALUES(CHILD_SHORT_DESCRIPTION), CHILD_COMMITMENT= VALUES(CHILD_COMMITMENT), PARENT_START_DATETIME= VALUES(PARENT_START_DATETIME), PARENT_IDENTIFIER= VALUES(PARENT_IDENTIFIER), IS_PARENT_HIDDEN= VALUES(IS_PARENT_HIDDEN), PARENT_TITLE= VALUES(PARENT_TITLE); IF i_childId IS NOT NULL THEN DELETE FROM APP_M_V_VIEW WHERE OBJECT_ID_PK IN (SELECT OBJECT_ID_PK FROM APP_OBJECT where IS_ACTIVE<>1 and CHILD_ID_FK=i_childId); END IF; END$$ DELIMITER ;