EpicUUID: 5143F74D-DB01-4131-AAA3-52F4753E50D4 The ACCESS_LOG table has one row per event logging event In production environments this is a large table! Use care when querying this table outside the training environments. The ACCESS_TIME column holds the date and time when the event happened You have been tasked with returning information about event logging events in a specified date range, say January 2017. Is comparing the date directly... SELECT * FROM ACCESS_LOG WHERE '1/1/2017' <= ACCESS_TIME AND ACCESS_TIME < '2/1/2017' ...or with functions... SELECT * FROM ACCESS_LOG WHERE MONTH( ACCESS_TIME ) = 1 AND YEAR( ACCESS_TIME ) = 2017 ...likely to be more efficient? A check on the indexed columns... SP_HELPINDEX ACCESS_LOG ...shows that ACCESS_TIME is an indexed column. Wrapping that column in a function may negate the use of this index. We'd like the index to be used since ACCESS_LOG is a large table and the ACCESS_TIME column is the main ﴾in this case, only﴿ column we're filtering on. Therefore, comparing with dates directly is likely to be more efficient than using the functions. Performance 8 • 16 RPT101i SQL I 201
EpicUUID: 5143F74D-DB01-4131-AAA3-52F4753E50D4 Keep it Simple Recall that SQL is a declarative language. If your query simply describes what you want your result to look like, you allow SQL to evaluate potentially many ways of producing the result. SQL will then choose the way that is evaluated to be the most efficient. If your query includes complexities that describe how SQL should generate the result, then you may be limiting SQL's options. With a simpler query, there may be more options and the query will likely perform better. You can keep a query simple by avoiding unnecessary tables, columns, operators, functions, comparisons, and even clauses. Since keeping a query simple also has the benefit of making the query easier to create, you've probably already been keeping your queries simple throughout this training. However, views can hide the complexity of the query that is actually being evaluated by SQL. Therefore, extra care should be taken when using views in a query. Recall that a view, unlike a table or a materialized view, does not itself hold any data. Instead, it holds a query which is evaluated as part of the entire query in which it is referenced. Therefore, consider how the view is defined when writing a query that references a view. 8 • 17 Performance 202 RPT101i SQL I
EpicUUID: 5143F74D-DB01-4131-AAA3-52F4753E50D4 The view V_PAT_FACT returns one row per patient. The PAT_NAME returns the patient's name The SEX_C column returns a sex indicator ﴾'1' for 'Female', '2' for 'Male'﴿ The SEX_NAME column returns the sex ﴾'Female', 'Male'﴿ Consider the two following queries: ‐‐(1) Filter on SEX_C SELECT PAT_NAME FROM V_PAT_FACT WHERE SEX_C = '1' ‐‐(2) Filter on SEX_NAME SELECT PAT_NAME FROM V_PAT_FACT WHERE SEX_NAME = 'Female' Both appear similar in that they reference the same view and column, and they both have a string comparison on one additional ﴾though different﴿ column. Without knowing how the view works, we may expect the performance of the two queries to be similar. Here's what the definition of the view looks like: SELECT /* Some columns */ pat.PAT_NAME as 'PAT_NAME' /* Some more columns */ ,pat.SEX_C as 'SEX_C' ,coalesce(sex.NAME, '*No sex recorded') as 'SEX_NAME' /* Some more columns */ FROM PATIENT pat /* Some more tables */ LEFT OUTER JOIN ZC_SEX sex ON pat.SEX_C=sex.RCPT_MEM_SEX_C Notice that the PAT_NAME and SEX_C columns are being pulled from the PATIENT table while the SEX_NAME column is being calculated by using the additional ZC_SEX table. Therefore, the first query ﴾filter on SEX_C﴿ is likely to be more efficient because when SQL processes it, SQL may opt to ignore the ZC_SEX table altogether. Performance 8 • 18 RPT101i SQL I 203
EpicUUID: 5143F74D-DB01-4131-AAA3-52F4753E50D4 Reviewing the Chapter Review Questions 1. How can you use fewer rows while testing a query? 2. How can you determine which columns are indexed? 3. True or False: There is a bigger performance concern when querying a view than when querying a table or materialized view. 4. Follow‐up to the previous question: Why? Review Key 8 • 19 Performance 204 RPT101i SQL I
EpicUUID: 5143F74D-DB01-4131-AAA3-52F4753E50D4 Review Key 1. How can you use fewer rows while testing a query? * SQL Server: SELECT TOP statement * Oracle: ROWNUM pseudocolumn 2. How can you determine which columns are indexed? * SQL Server: call the SP_HELPINDEX stored procedure * Oracle: query the ALL_IND_COLUMNS table 3. True or False: There is a bigger performance concern when querying a view than when querying a table or materialized view. True 4. Follow‐up to the previous question: Why? When querying a table or materialized view, you can see what will be queried: a single database object with columns that hold data. When querying a view, any number of tables and complexities may need to be processed by SQL. Study Checklist Performance 8 • 20 RPT101i SQL I 205
EpicUUID: 5143F74D-DB01-4131-AAA3-52F4753E50D4 Study Checklist Make sure you can define the following key terms: ☐ Index Make sure you can perform the following tasks: ☐ Limit the number of rows returned by a SQL query ☐ List the indexes for a table ☐ Interpret an existing SQL query Make sure you fully understand and can explain the following concepts: ☐ Why indexed columns are preferred ☐ How to use functions efficiently 8 • 21 Performance 206 RPT101i SQL I
EpicUUID: 5143F74D-DB01-4131-AAA3-52F4753E50D4 ©2019 ‐ 2023 Epic Systems Corporation. All rights reserved. PROPRIETARY INFORMATION ‐ This item and its contents may not be accessed, used, modified, reproduced, performed, displayed, distributed or disclosed unless and only to the extent expressly authorized by an agreement with Epic. This item is a Commercial Item, as that term is defined at 48 C.F.R. Sec. 2.101. It contains trade secrets and commercial information that are confidential, privileged, and exempt from disclosure under the Freedom of Information Act and prohibited from disclosure under the Trade Secrets Act. After Visit Summary, App Orchard, ASAP, Aura, Beacon, Beaker, Beans, BedTime, Best Care for My Patient, Bones, Break‐the‐Glass, Bugsy, Caboodle, Cadence, Canto, Care Everywhere, Charge Router, Cheers, Chronicles, Clarity, Cogito ergo sum, Cohort, Comfort, Community Connect, Compass Rose, Cosmos, Cupid, Epic, EpicCare, EpicCare Link, Epicenter, EpicLink, EpicShare, EpicWeb, Epic Earth, Epic Research, Garden Plot, Grand Central, Haiku, Happy Together, Healthy Planet, Hello World, Hey Epic!, Hyperdrive, Hyperspace, Kaleidoscope, Kit, Limerick, Lucy, Lumens, MyChart, Nebula, OpTime, OutReach, Patients Like Mine, Phoenix, Powered by Epic, Prelude, Radar, Radiant, Resolute, Revenue Guardian, Rover, Share Everywhere, SmartForms, Sonnet, Stork, System Pulse, Tapestry, Trove, Welcome, Willow, Wisdom, With the Patient at Heart, and WorldWise are registered trademarks, trademarks, or service marks of Epic Systems Corporation in the United States of America and/or other countries. Other company, product, and service names referenced herein may be trademarks or service marks of their respective owners. Patents Notice: www.epic.com/patents. Performance 8 • 22 RPT101i SQL I 207