Oracle SQL & PL/SQL Optimization for Developers Documentation
Total Page:16
File Type:pdf, Size:1020Kb
Oracle SQL & PL/SQL Optimization for Developers Documentation Release 2.5.0 Ian Hellström Jul 22, 2021 Contents 1 Introduction 1 1.1 Why This Guide?.............................................1 1.2 System and User Requirements.....................................2 1.3 Notes...................................................2 2 SQL 5 2.1 SQL Basics................................................6 2.1.1 Style Guide...........................................7 2.1.1.1 Conventions......................................7 2.1.1.2 Capitalization.....................................7 2.1.1.3 Semicolons......................................8 2.1.1.4 Asterisks........................................8 2.1.1.5 Thrift..........................................8 2.1.1.6 Aliases.........................................8 2.1.1.7 Comments.......................................9 2.1.1.8 Constraints.......................................9 2.1.1.9 Respect........................................9 2.1.1.10 Formatting....................................... 10 2.1.1.11 Coding Guidelines................................... 10 2.1.2 Query Processing Order.................................... 10 2.2 Execution Plans............................................. 12 2.2.1 Explain Plan........................................... 14 2.2.1.1 Cardinality....................................... 15 2.2.1.2 Access Methods.................................... 15 2.2.1.3 Join Methods..................................... 18 2.2.1.4 Join Types....................................... 19 2.2.1.5 Join Orders....................................... 19 2.2.1.6 Partition Pruning.................................... 19 2.2.1.7 Parallel Execution................................... 20 2.2.2 Adaptive Query Optimization................................. 21 2.3 Indexes.................................................. 22 2.3.1 Developer or Admin?...................................... 23 2.3.2 Access Paths and Indexes.................................... 24 2.3.3 Statistics............................................. 24 2.3.4 Predicates: Equality before Inequality............................. 25 2.3.5 Predicates: LHS vs RHS.................................... 28 i 2.3.6 Function-Based Indexes and NULLs.............................. 29 2.3.7 Predicates: The WHERE Clause................................. 30 2.3.8 Full Table Scans......................................... 32 2.3.9 Top-N Queries and Pagination................................. 32 2.3.10 Index-Organized Tables..................................... 33 2.3.11 Beyond B-Trees: Bitmap Indexes................................ 34 2.4 Subqueries................................................ 34 2.4.1 Scalar Subqueries........................................ 34 2.4.2 Nested and Correlated Subqueries............................... 35 2.4.3 Subquery Unnesting...................................... 35 2.4.4 Combined Nested Subqueries.................................. 36 2.4.5 Subqueries with DISTINCT .................................. 37 2.4.6 Inline Views and Factored Subqueries............................. 38 2.5 Joins................................................... 40 2.5.1 Nested Loops.......................................... 42 2.5.2 Hash Join............................................ 43 2.5.2.1 Join Orders and Join Trees.............................. 43 2.5.2.2 Partitioned Hash Joins................................. 45 2.5.3 Sort-Merge Join......................................... 45 2.5.4 Join Performance: ON vs WHERE ................................ 46 2.6 Hints................................................... 47 2.6.1 When To Use Hints....................................... 47 2.6.2 When Not To Use Hints..................................... 48 2.6.3 Named Query Blocks...................................... 49 2.6.4 Global Hints........................................... 49 2.6.5 Types of Hints.......................................... 49 2.6.5.1 Optimization Goals and Approaches......................... 50 2.6.5.2 Optimizer Hints.................................... 50 2.6.5.3 Access Path Hints................................... 51 2.6.5.4 Join Order Hints.................................... 52 2.6.5.5 Join Operation Hints.................................. 52 2.6.5.6 Parallel Execution Hints................................ 54 2.6.5.7 Query Transformation Hints.............................. 56 2.6.5.8 Miscellaneous Hints.................................. 58 2.6.6 SQL Optimization Techniques................................. 62 3 PL/SQL 65 3.1 Compilation............................................... 66 3.2 Bind Variables.............................................. 67 3.2.1 PL/SQL Variables........................................ 67 3.2.2 Bind Peeking.......................................... 69 3.2.3 Adaptive Cursor Sharing and Adaptive Execution Plans.................... 69 3.2.4 Generic Static Statements.................................... 70 3.3 Loops, Cursors, and Bulk Operations.................................. 71 3.3.1 Collections........................................... 72 3.3.2 Performance Comparisons................................... 73 3.3.2.1 Explicit vs Implicit Cursors.............................. 73 3.3.2.2 The Impact of Context Switches........................... 74 3.3.2.3 Table Functions.................................... 74 3.3.3 Caveats............................................. 76 3.4 Caching.................................................. 76 3.4.1 Side Effects........................................... 76 3.4.2 Alternatives........................................... 77 3.4.2.1 DETERMINISTIC Functions............................. 78 ii 3.4.2.2 The RESULT_CACHE Option............................. 78 3.4.2.3 DETERMINISTIC vs RESULT_CACHE ....................... 80 3.4.3 The UDF Pragma........................................ 81 3.4.4 The NOCOPY Directive: To Pass By Value or Reference?................... 81 4 Data Modelling 83 4.1 Partitioning................................................ 83 4.1.1 Partitioned Indexes....................................... 84 4.1.2 Caveats............................................. 85 4.1.3 Recommendations....................................... 85 4.1.3.1 Single-Level Partitioning............................... 86 4.1.3.2 Composite Partitioning................................ 86 4.1.3.3 Prefixed vs Non-Prefixed Local Indexes....................... 86 4.1.3.4 Partitioned vs Non-Partitioned Global Indexes.................... 86 4.2 Compression............................................... 87 4.2.1 Compression Methods..................................... 87 4.2.1.1 BASIC and OLTP ................................... 87 4.2.1.2 Hybrid Columnar Compression............................ 88 4.2.2 Performance Considerations.................................. 88 4.2.2.1 Size Reduction..................................... 88 4.2.2.2 CPU Overhead..................................... 89 5 Glossary 91 Bibliography 95 Index 97 iii iv CHAPTER 1 Introduction SQL is a peculiar language. It is one of only a handful of fourth-generation programming languages (4GL) in general use today, it seems deceptively simple, and more often than not you have many quite disparate options at your disposal to get the results you want, but only few of the alternatives perform well in production environments. The simplicity of the language veils decades of research and development, and although the syntax feels (almost) immediately familiar, perhaps even natural, it is a language that you have to wrap your head around. People coming from imperative languages often think in terms of consecutive instructions: relational databases operate on sets not single entities. How the SQL optimizer decides to execute the query may not coincide with what you think it will (or ought to) do. To the untrained eye a database developer can seem like a sorcerer, and it is often said that query tuning through interpreting execution plans is more art than science. This could not be further from the truth: a thorough understanding of the inner workings of any database is essential to squeeze out every last millisecond of performance. The problem is: the information is scattered all over the place, so finding exactly what you need when you need it can be a daunting task. 1.1 Why This Guide? While it’s easy to write bad code in any programming language, SQL — and to some extent PL/SQL too — is particularly susceptible. The reason is simple: because of its natural-looking syntax and the fact that a lot of technical ‘stuff’ goes on behind the scenes, some of which is not always obvious to all but seasoned developers and DBAs, people often forget that they are still dealing with a programming language and that SQL is not a silver bullet. Just because it looks easy does not mean that it is. We don’t want to step on anyone’s toes but frequently production SQL code (e.g. reports) is created not by developers but business users who often lack the know-how to create quality code. It’s not necessarily their jobs to come up with efficient queries but it is not uncommon to hear their gripes afterwards, once they discover that a report takes ‘too long’ because the database is ‘too slow’. The fact of the matter is that they have run into one of many traps, such as non-SARGable predicates, bad (or no) use of indexes, unnecessarily complicated (nested) subqueries that not even their creator can understand after a short lunch break but somehow