{"id":9417,"date":"2019-12-13T18:24:17","date_gmt":"2019-12-13T17:24:17","guid":{"rendered":"https:\/\/www.salvis.com\/blog\/?p=9417"},"modified":"2023-11-08T10:55:47","modified_gmt":"2023-11-08T09:55:47","slug":"constants-vs-parameterless-functions","status":"publish","type":"post","link":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/","title":{"rendered":"Constants vs. Parameterless Functions"},"content":{"rendered":"\n<p>Do you use parameterless PL\/SQL functions in your queries? Did you know that this may cause performance issues? In this blog post, I explain why parameterless functions can be the reason for bad execution plans in any Oracle Database.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan.png\"><img loading=\"lazy\" decoding=\"async\" width=\"686\" height=\"360\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan.png\" alt=\"\" class=\"wp-image-9432\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan.png 686w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan-300x157.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan-260x136.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan-50x26.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan-143x75.png 143w\" sizes=\"auto, (max-width:767px) 480px, 686px\" \/><\/a><\/figure>\n\n\n\n<p>I recently had to analyze this problem in a production system and thought it was worth sharing. On the one hand, because we did not find a satisfactory solution and on the other hand because this could change in the future when we start discussing it.<\/p>\n\n\n\n<p>For this blog post, I used an Oracle Database 19c Enterprise Edition, version 19.5.0.0.0 in a Docker environment. However, you can run the scripts in any edition of an Oracle Database 12c Release 1 or later to reproduce the results.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Data Setup<\/h2>\n\n\n\n<p>We create a user <code>demo<\/code>&nbsp; with <code>ALTER SESSION<\/code> and <code>SELECT ANY DICTIONARY<\/code> privileges as follows:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Create user demo<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE USER demo IDENTIFIED BY demo  \nDEFAULT TABLESPACE users\nTEMPORARY TABLESPACE temp\nQUOTA UNLIMITED ON users;\n\nGRANT connect, resource TO demo;\nGRANT alter session TO demo;\nGRANT select any dictionary TO demo;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">USER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">demo<\/span><span style=\"color: #D4D4D4\"> IDENTIFIED <\/span><span style=\"color: #569CD6\">BY<\/span><span style=\"color: #D4D4D4\"> demo  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">DEFAULT<\/span><span style=\"color: #D4D4D4\"> TABLESPACE users<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">TEMPORARY TABLESPACE temp<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">QUOTA <\/span><span style=\"color: #569CD6\">UNLIMITED<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">ON<\/span><span style=\"color: #D4D4D4\"> users;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">GRANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">connect<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">resource<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">TO<\/span><span style=\"color: #D4D4D4\"> demo;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">GRANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">alter<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">session<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">TO<\/span><span style=\"color: #D4D4D4\"> demo;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">GRANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">select<\/span><span style=\"color: #D4D4D4\"> any dictionary <\/span><span style=\"color: #569CD6\">TO<\/span><span style=\"color: #D4D4D4\"> demo;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Then as user <code>demo<\/code> we create a table <code>t<\/code> with an index <code>t_ind_idx<\/code> on column <code>ind<\/code><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Create table t<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE TABLE t (\n   id   INTEGER       GENERATED ALWAYS AS IDENTITY CONSTRAINT t_pk PRIMARY KEY,\n   ind  INTEGER       NOT NULL CONSTRAINT ind_ck CHECK (ind IN (0, 1)), \n   text VARCHAR2(100) NOT NULL\n);\nCREATE INDEX t_ind_idx ON t (ind);\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">TABLE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">t<\/span><span style=\"color: #D4D4D4\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   id   <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\">       <\/span><span style=\"color: #569CD6\">GENERATED<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">ALWAYS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">AS<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IDENTITY<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">CONSTRAINT<\/span><span style=\"color: #D4D4D4\"> t_pk <\/span><span style=\"color: #569CD6\">PRIMARY KEY<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ind  <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\">       <\/span><span style=\"color: #569CD6\">NOT NULL<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">CONSTRAINT<\/span><span style=\"color: #D4D4D4\"> ind_ck <\/span><span style=\"color: #569CD6\">CHECK<\/span><span style=\"color: #D4D4D4\"> (ind <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">)), <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">text<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">VARCHAR2<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">100<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">NOT NULL<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">CREATE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INDEX<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">t_ind_idx<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">ON<\/span><span style=\"color: #D4D4D4\"> t (ind);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>and populated table <code>t<\/code> with the following anonymous PL\/SQL block:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Populate table t<\/span><span role=\"button\" tabindex=\"0\" data-code=\"BEGIN\n   dbms_random.seed(0);\n   INSERT INTO t (ind, text)\n   SELECT CASE \n             WHEN dbms_random.value(0, 999) < 1 THEN\n                1 \n             ELSE \n                0\n          END AS ind,\n          dbms_random.string('p', round(dbms_random.value(5, 100),0)) AS text\n     FROM xmltable('1 to 100000');\n   COMMIT;\nEND;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #DCDCAA\">dbms_random.<\/span><span style=\"color: #4EC9B0\">seed<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">INSERT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTO<\/span><span style=\"color: #D4D4D4\"> t (ind, text)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">CASE<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">             <\/span><span style=\"color: #569CD6\">WHEN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">dbms_random.<\/span><span style=\"color: #4EC9B0\">value<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">999<\/span><span style=\"color: #D4D4D4\">) &lt; <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">THEN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">             <\/span><span style=\"color: #C586C0\">ELSE<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #B5CEA8\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">AS<\/span><span style=\"color: #D4D4D4\"> ind,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #DCDCAA\">dbms_random.<\/span><span style=\"color: #4EC9B0\">string<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;p&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #DCDCAA\">round<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #DCDCAA\">dbms_random.<\/span><span style=\"color: #4EC9B0\">value<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">5<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">100<\/span><span style=\"color: #D4D4D4\">),<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)) <\/span><span style=\"color: #569CD6\">AS<\/span><span style=\"color: #D4D4D4\"> text<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">     <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">xmltable<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;1 to 100000&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #DCDCAA\">COMMIT<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The case expression leads to a skewed distribution of column <code>ind<\/code>. Only around 0.1% of the rows have a value <code>1<\/code> as the following query shows:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Distribution of column ind<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SELECT ind, count(*) \n  FROM t \n GROUP BY ind;\n\n       IND   COUNT(*)\n---------- ----------\n         1        101\n         0      99899\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> ind, <\/span><span style=\"color: #DCDCAA\">count<\/span><span style=\"color: #D4D4D4\">(*) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> t <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">GROUP BY<\/span><span style=\"color: #D4D4D4\"> ind;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       IND   <\/span><span style=\"color: #DCDCAA\">COUNT<\/span><span style=\"color: #D4D4D4\">(*)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">---------- ----------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #B5CEA8\">101<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #B5CEA8\">99899<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Therefore we are gathering statistics for table <code>t<\/code>&nbsp; with a histogram for column <code>ind<\/code>:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Gather statistics<\/span><span role=\"button\" tabindex=\"0\" data-code=\"BEGIN\n   dbms_stats.gather_table_stats(\n      ownname    =&gt; user, \n      tabname    =&gt; 'T', \n      method_opt =&gt; 'FOR ALL COLUMNS SIZE AUTO FOR COLUMNS SIZE 2 IND'\n   );\nEND;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #DCDCAA\">dbms_stats.<\/span><span style=\"color: #4EC9B0\">gather_table_stats<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      ownname    =&gt; <\/span><span style=\"color: #DCDCAA\">user<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      tabname    =&gt; <\/span><span style=\"color: #CE9178\">&#39;T&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      method_opt =&gt; <\/span><span style=\"color: #CE9178\">&#39;FOR ALL COLUMNS SIZE AUTO FOR COLUMNS SIZE 2 IND&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   );<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Now, we can check the histogram with the following query:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Histogramm of column ind<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SELECT endpoint_value, endpoint_number \n  FROM user_histograms\n WHERE table_name = 'T' \n   AND column_name = 'IND';\n\nENDPOINT_VALUE ENDPOINT_NUMBER\n-------------- ---------------\n             0           99899\n             1          100000\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> endpoint_value, endpoint_number <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> user_histograms<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">WHERE<\/span><span style=\"color: #D4D4D4\"> table_name = <\/span><span style=\"color: #CE9178\">&#39;T&#39;<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">AND<\/span><span style=\"color: #D4D4D4\"> column_name = <\/span><span style=\"color: #CE9178\">&#39;IND&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ENDPOINT_VALUE ENDPOINT_NUMBER<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">-------------- ---------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">             <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">           <\/span><span style=\"color: #B5CEA8\">99899<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">             <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #B5CEA8\">100000<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Two rows for the two values of column <code>ind<\/code>. For value <code>0<\/code> we expect 99899 rows (endpoints) and for value <code>1<\/code>&nbsp; we expect 101 rows (100000 &#8211; 99899 endpoints). This is 100 percent accurate.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Constant Declaration<\/h2>\n\n\n\n<p>In the <a href=\"https:\/\/trivadis.github.io\/plsql-and-sql-coding-guidelines\/v3.6\/4-language-usage\/1-general\/g-1050\/\">Trivadis PL\/SQL &amp; SQL Guidelines<\/a> we recommend avoiding the use of literals in PL\/SQL code. Every time we see a literal in a PL\/SQL code we should consider using a constant instead. Often this makes sense because the name of the constant is more meaningful than the literal, making the code more readable and maintainable.<\/p>\n\n\n\n<p>Hence we create the following PL\/SQL package for our representation of boolean values in SQL:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">PL\/SQL package for boolean values<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE const_boolean AUTHID DEFINER IS\n   co_true  CONSTANT INTEGER := 1;\n   co_false CONSTANT INTEGER := 0;\nEND const_boolean;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">const_boolean<\/span><span style=\"color: #D4D4D4\"> AUTHID DEFINER <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">   co_true  <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   co_false <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> const_boolean;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Now we can use these constants in our PL\/SQL code as follows:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">SQL using a constant (within PL\/SQL)<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SET SERVEROUTPUT ON\nBEGIN\n   FOR r IN (\n      SELECT count(*) AS open_count\n        FROM t \n       WHERE ind = const_boolean.co_true\n   ) LOOP\n      dbms_output.put_line('open: ' || r.open_count);\n   END LOOP;\nEND;\n\/\n\nopen: 101\n\nPL\/SQL procedure successfully completed.\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">SET<\/span><span style=\"color: #D4D4D4\"> SERVEROUTPUT <\/span><span style=\"color: #569CD6\">ON<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #C586C0\">FOR<\/span><span style=\"color: #D4D4D4\"> r <\/span><span style=\"color: #569CD6\">IN<\/span><span style=\"color: #D4D4D4\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">count<\/span><span style=\"color: #D4D4D4\">(*) <\/span><span style=\"color: #569CD6\">AS<\/span><span style=\"color: #D4D4D4\"> open_count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> t <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       <\/span><span style=\"color: #569CD6\">WHERE<\/span><span style=\"color: #D4D4D4\"> ind = const_boolean.co_true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   ) <\/span><span style=\"color: #C586C0\">LOOP<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #DCDCAA\">dbms_output.<\/span><span style=\"color: #4EC9B0\">put_line<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;open: &#39;<\/span><span style=\"color: #D4D4D4\"> || r.open_count);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #C586C0\">END LOOP<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">open<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">101<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">PL\/<\/span><span style=\"color: #569CD6\">SQL<\/span><span style=\"color: #D4D4D4\"> procedure successfully completed.<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>When developing complex SQL statements I often run them standalone in an IDE until I&#8217;m satisfied with the result. But when we run this<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">SQL using a constant (outside of PL\/SQL)<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SELECT count(*) AS open_count\n  FROM t \n WHERE ind = const_boolean.co_true;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">count<\/span><span style=\"color: #D4D4D4\">(*) <\/span><span style=\"color: #569CD6\">AS<\/span><span style=\"color: #D4D4D4\"> open_count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> t <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">WHERE<\/span><span style=\"color: #D4D4D4\"> ind = const_boolean.co_true;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>we get the following error message:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Error when using a constant in SQL<\/span><span role=\"button\" tabindex=\"0\" data-code=\"Error starting at line : 1 in command -\nSELECT count(*) AS open_count\n  FROM t \n WHERE ind = const_boolean.co_true\nError at Command Line : 3 Column : 14\nError report -\nSQL Error: ORA-06553: PLS-221: 'CO_TRUE' is not a procedure or is undefined\n06553. 00000 -  &quot;PLS-%s: %s&quot;\n*Cause:    \n*Action:\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">Error starting at line : 1 in command -<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">SELECT count(*) AS open_count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  FROM t <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> WHERE ind = const_boolean.co_true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Error at Command Line : 3 Column : 14<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Error report -<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">SQL Error: ORA-06553: PLS-221: &#39;CO_TRUE&#39; is not a procedure or is undefined<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">06553. 00000 -  &quot;PLS-%s: %s&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">*Cause:    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">*Action:<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>We have to change the constant <code>const_boolean.co_true<\/code>&nbsp; to a literal (<code>1<\/code>), which is cumbersome and error-prone.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Parameterless Functions for Constants<\/h2>\n\n\n\n<p>As a workaround, we can create a parameterless function for each constant. Like this:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Parameterless function for each constant<\/span><span role=\"button\" tabindex=\"0\" data-code=\"CREATE OR REPLACE PACKAGE const_boolean AUTHID DEFINER IS\n   co_true  CONSTANT INTEGER := 1;\n   co_false CONSTANT INTEGER := 0;\n   FUNCTION true# RETURN INTEGER DETERMINISTIC;\n   FUNCTION false# RETURN INTEGER DETERMINISTIC;\nEND const_boolean;\n\/\nCREATE OR REPLACE PACKAGE BODY const_boolean IS\n   FUNCTION true# RETURN INTEGER DETERMINISTIC IS\n   BEGIN\n      RETURN co_true;\n   END true#;\n   FUNCTION false# RETURN INTEGER DETERMINISTIC IS\n   BEGIN\n     RETURN co_false;\n   END false#;\nEND const_boolean;\n\/\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">const_boolean<\/span><span style=\"color: #D4D4D4\"> AUTHID DEFINER <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   co_true  <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   co_false <\/span><span style=\"color: #569CD6\">CONSTANT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> := <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">true<\/span><span style=\"color: #D4D4D4\"># <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">false<\/span><span style=\"color: #D4D4D4\"># <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> const_boolean;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">CREATE OR REPLACE<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">PACKAGE BODY<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">const_boolean<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">true<\/span><span style=\"color: #D4D4D4\"># <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> co_true;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">#;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">FUNCTION<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">false<\/span><span style=\"color: #D4D4D4\"># <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">INTEGER<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">DETERMINISTIC<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">IS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">BEGIN<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">     <\/span><span style=\"color: #C586C0\">RETURN<\/span><span style=\"color: #D4D4D4\"> co_false;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">#;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">END<\/span><span style=\"color: #D4D4D4\"> const_boolean;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\/<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Now we can use the function in PL\/SQL and SQL like this:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">SQL<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SELECT count(*) AS open_count\n  FROM t \n WHERE ind = const_boolean.true#;\n\nOPEN_COUNT\n----------\n       101\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">count<\/span><span style=\"color: #D4D4D4\">(*) <\/span><span style=\"color: #569CD6\">AS<\/span><span style=\"color: #D4D4D4\"> open_count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> t <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">WHERE<\/span><span style=\"color: #D4D4D4\"> ind = const_boolean.true#;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">OPEN_COUNT<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">----------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">       <\/span><span style=\"color: #B5CEA8\">101<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>So far so good.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. The Problem<\/h2>\n\n\n\n<p>The execution plan of the previous statement looks as follows:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Bad execution plan<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SQL_ID  bg67gqa8f48j8, child number 0\n-------------------------------------\nSELECT count(*) AS open_count  FROM t  WHERE ind = const_boolean.true#\n \nPlan hash value: 3395265327\n \n-----------------------------------------------------------------------------------\n| Id  | Operation             | Name      | Rows  | Bytes | Cost (%CPU)| Time     |\n-----------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT      |           |       |       |    75 (100)|          |\n|   1 |  SORT AGGREGATE       |           |     1 |     3 |            |          |\n|*  2 |   INDEX FAST FULL SCAN| T_IND_IDX | 50000 |   146K|    75  (12)| 00:00:01 |\n-----------------------------------------------------------------------------------\n \nPredicate Information (identified by operation id):\n---------------------------------------------------\n \n   2 - filter(&quot;IND&quot;=&quot;CONST_BOOLEAN&quot;.&quot;TRUE#&quot;())\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">SQL_ID  bg67gqa8f48j8, child number 0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">SELECT count(*) AS open_count  FROM t  WHERE ind = const_boolean.true#<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Plan hash value: 3395265327<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-----------------------------------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">| Id  | Operation             | Name      | Rows  | Bytes | Cost (%CPU)| Time     |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-----------------------------------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">|   0 | SELECT STATEMENT      |           |       |       |    75 (100)|          |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">|   1 |  SORT AGGREGATE       |           |     1 |     3 |            |          |<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">|*  2 |   INDEX FAST FULL SCAN| T_IND_IDX | 50000 |   146K|    75  (12)| 00:00:01 |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-----------------------------------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Predicate Information (identified by operation id):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">---------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   2 - filter(&quot;IND&quot;=&quot;CONST_BOOLEAN&quot;.&quot;TRUE#&quot;())<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>When you look at line 12 you see that the optimizer estimates to process 50000 rows. That&#8217;s 50 percent of all rows. This is based on the number of distinct values for column <code>ind<\/code> and the number of rows in the table <code>t<\/code>. The optimizer gets this information from here:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Table and column statistics<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SELECT num_rows \n  FROM user_tables \n WHERE table_name = 'T';\n\n  NUM_ROWS\n----------\n    100000\n\nSELECT num_distinct \n  FROM user_tab_columns\n WHERE table_name = 'T'\n   AND column_name = 'IND';\n\nNUM_DISTINCT\n------------\n           2\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> num_rows <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> user_tables <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">WHERE<\/span><span style=\"color: #D4D4D4\"> table_name = <\/span><span style=\"color: #CE9178\">&#39;T&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  NUM_ROWS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">----------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #B5CEA8\">100000<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">SELECT<\/span><span style=\"color: #D4D4D4\"> num_distinct <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">FROM<\/span><span style=\"color: #D4D4D4\"> user_tab_columns<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">WHERE<\/span><span style=\"color: #D4D4D4\"> table_name = <\/span><span style=\"color: #CE9178\">&#39;T&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #569CD6\">AND<\/span><span style=\"color: #D4D4D4\"> column_name = <\/span><span style=\"color: #CE9178\">&#39;IND&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">NUM_DISTINCT<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">           <\/span><span style=\"color: #B5CEA8\">2<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Unfortunately, the histogram for the column <code>ind<\/code> is ignored. Why? Because the Oracle Database has no idea what the value of <code>const_boolean.true#<\/code>\u00a0 is. Hence, a histogram is not helpful in finding an execution plan.<\/p>\n\n\n\n<p>An optimal plan would look like this:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">Good execution plan<\/span><span role=\"button\" tabindex=\"0\" data-code=\"SQL_ID  bstdc2tsv1qcw, child number 0\n-------------------------------------\nSELECT count(*) AS open_count  FROM t  WHERE ind = 1\n \nPlan hash value: 3365671116\n \n-------------------------------------------------------------------------------\n| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |\n-------------------------------------------------------------------------------\n|   0 | SELECT STATEMENT  |           |       |       |     1 (100)|          |\n|   1 |  SORT AGGREGATE   |           |     1 |     3 |            |          |\n|*  2 |   INDEX RANGE SCAN| T_IND_IDX |   101 |   303 |     1   (0)| 00:00:01 |\n-------------------------------------------------------------------------------\n \nPredicate Information (identified by operation id):\n---------------------------------------------------\n \n   2 - access(&quot;IND&quot;=1)\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">SQL_ID  bstdc2tsv1qcw, child number 0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">SELECT count(*) AS open_count  FROM t  WHERE ind = 1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Plan hash value: 3365671116<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-------------------------------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-------------------------------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">|   0 | SELECT STATEMENT  |           |       |       |     1 (100)|          |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">|   1 |  SORT AGGREGATE   |           |     1 |     3 |            |          |<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">|*  2 |   INDEX RANGE SCAN| T_IND_IDX |   101 |   303 |     1   (0)| 00:00:01 |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-------------------------------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Predicate Information (identified by operation id):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">---------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   2 - access(&quot;IND&quot;=1)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>When you look at line 12, you see that<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>an <code>INDEX RANGE SCAN<\/code> is used and<\/li>\n\n\n\n<li>the number of rows is estimated correctly.<\/li>\n<\/ol>\n\n\n\n<p>We get this plan when using a literal <code>1<\/code>, a bind variable with the bind value <code>1<\/code> (thanks to bind variable peeking) or a constant with value <code>1<\/code> (which is treated as a bind variable in PL\/SQL).<\/p>\n\n\n\n<p>The wrong cardinality is a major problem. Because the cardinality is the most important criterion for choosing an optimal access method, join order and join method. Bad cardinality estimates lead to bad execution plans and bad performance. This cannot be ignored, even if in this demo case the resulting performance is still okay.<\/p>\n\n\n\n<p>The problem occurs only if we are accessing columns with significantly skewed data and if these columns have a histogram.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Workarounds<\/h2>\n\n\n\n<p>We have basically three options to work around the problem:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>For PL\/SQL code we can use a constant instead of a parameterless function<br \/>(e.g. <code>ind = const_boolean.co_true<\/code>)<\/li>\n\n\n\n<li>For PL\/SQL code or plain SQL like in views, we can use a literal with a comment instead of a parameterless function<br \/>(e.g. <code>ind = 1 -- const_boolean.co_true<\/code>)<\/li>\n\n\n\n<li><em>For PL\/SQL code or plain SQL like in views, we can query the parameterless function in a subquery and force the optimizer to execute it during parse time [added on 2019-12-14]<\/em><br \/><em>(e.g. <code>ind IN (SELECT \/*+ precompute_subquery *\/ const_boolean.true# FROM DUAL)<\/code>)<\/em><\/li>\n<\/ol>\n\n\n\n<p>The first option has the drawback, that you have to change the SQL to make it runnable outside of PL\/SQL. The second option may lead to inconsistencies due to wrong literal\/comment combinations or when changing constant values. <em>The third option requires an <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/IN-Condition.html#GUID-C7961CB3-8F60-47E0-96EB-BDCF5DB1317C\">IN condition<\/a> that could be accidentally changed to an <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/Comparison-Conditions.html#GUID-2590303E-81FE-4758-A971-1EE8B798951F\">equal comparison condition<\/a> due to the <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/Scalar-Subquery-Expressions.html#GUID-475D80C3-C873-4475-AB1A-8837C5CF8CE4\">scalar subquery<\/a>, which would make the undocumented <a href=\"https:\/\/blog.tanelpoder.com\/2009\/01\/23\/multipart-cursor-subexecution-and-precompute_subquery-hint\/\">precompute_subquery hint<\/a> ineffective. [added on 2019-12-14]<\/em><\/p>\n\n\n\n<p>Of course, you can continue to use parameterless functions in SQL and PL\/SQL and switch to one of the options if there is a problem or if you know that a histogram exists for a certain column. But this is difficult to apply consistently. In fact, it makes maintenance more complicated with a certain performance risk or penalty.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Considered Alternatives<\/h2>\n\n\n\n<p>I had a look at <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/addci\/using-extensible-optimizer.html#GUID-90DC8855-4A40-480F-B574-4D82A227B4F4\">Associate Statistics (Extensible Optimizer Interface)<\/a>. This does not help, because there is no way to access the related table columns to calculate the impact on the selectivity. The feature is useful if a function gets some parameters to calculate the impact on the selectivity, but without parameters, this is not possible.<\/p>\n\n\n\n<p>I had considered <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/oracle-database\/19\/sqlrf\/CREATE-TABLE.html#GUID-F9CE0CC3-13AE-4744-A43C-EAC7A71AAAB6__I2146309\">list partitioned<\/a> tables based on skewed columns instead of using indexes. This works and can make sense to reduce the overhead of an index (especially indexing non-selective values). But the issues regarding parameterless functions are 100 percent the same.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Summary<\/h2>\n\n\n\n<p>Parameterless functions are a way to use constants in SQL outside of PL\/SQL, for example in views. However, they rob the optimizer of the capability to use histograms and therefore find an optimal execution plan.<\/p>\n\n\n\n<p>Actually, we can only work around the problem. The Oracle Database has to provide the solution. Either by allowing to access package global constants in SQL (outside of PL\/SQL) or by implementing some kind of peeking for parameterless, deterministic functions.<\/p>\n\n\n\n<p>If you think I missed something important, especially if you think there is a better workaround or even a solution, then please do not hesitate to leave a comment or contact me directly. Thank you.<\/p>\n\n\n\n<p><em>Updated on 2019-12-14, added a third option under &#8220;5. Workarounds&#8221; based on a <a href=\"https:\/\/twitter.com\/JLOracle\/status\/1205804594238050304\">tweet<\/a> by <a href=\"https:\/\/twitter.com\/JLOracle\">Jonathan Lewis<\/a>. Thanks a lot.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Do you use parameterless PL\/SQL functions in your queries? Did you know that this may cause performance issues? In this blog post, I explain why parameterless functions can be the reason for bad execution plans in any Oracle Database. I recently had to analyze this problem in a production system and thought<span class=\"excerpt-hellip\"> [\u2026]<\/span><\/p>\n","protected":false},"author":1,"featured_media":9432,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[25,13,85],"class_list":["post-9417","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-performance","tag-plsql","tag-sql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Constants vs. Parameterless Functions - Philipp Salvisberg&#039;s Blog<\/title>\n<meta name=\"description\" content=\"Parameterless functions are a way to use constants in SQL outside of PL\/SQL, for example in views. However, they rob the optimizer of the capability to use histograms and therefore finding an optimal execution plan. Actually we can only work around the problem. The Oracle Database has to provide the solution. Either by allowing to access package global constants in SQL (outside of PL\/SQL) or by implementing some kind of peeking for parameterless, deterministic functions.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Constants vs. Parameterless Functions - Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"Parameterless functions are a way to use constants in SQL outside of PL\/SQL, for example in views. However, they rob the optimizer of the capability to use histograms and therefore finding an optimal execution plan. Actually we can only work around the problem. The Oracle Database has to provide the solution. Either by allowing to access package global constants in SQL (outside of PL\/SQL) or by implementing some kind of peeking for parameterless, deterministic functions.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/\" \/>\n<meta property=\"og:site_name\" content=\"Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-12-13T17:24:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-11-08T09:55:47+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan.png\" \/>\n\t<meta property=\"og:image:width\" content=\"686\" \/>\n\t<meta property=\"og:image:height\" content=\"360\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Philipp Salvisberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:site\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Philipp Salvisberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/\"},\"author\":{\"name\":\"Philipp Salvisberg\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"headline\":\"Constants vs. Parameterless Functions\",\"datePublished\":\"2019-12-13T17:24:17+00:00\",\"dateModified\":\"2023-11-08T09:55:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/\"},\"wordCount\":1146,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/12\\\/bad_execution_plan.png\",\"keywords\":[\"Performance\",\"PL\\\/SQL\",\"SQL\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/\",\"name\":\"Constants vs. Parameterless Functions - Philipp Salvisberg&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/12\\\/bad_execution_plan.png\",\"datePublished\":\"2019-12-13T17:24:17+00:00\",\"dateModified\":\"2023-11-08T09:55:47+00:00\",\"description\":\"Parameterless functions are a way to use constants in SQL outside of PL\\\/SQL, for example in views. However, they rob the optimizer of the capability to use histograms and therefore finding an optimal execution plan. Actually we can only work around the problem. The Oracle Database has to provide the solution. Either by allowing to access package global constants in SQL (outside of PL\\\/SQL) or by implementing some kind of peeking for parameterless, deterministic functions.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/12\\\/bad_execution_plan.png\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/12\\\/bad_execution_plan.png\",\"width\":686,\"height\":360},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2019\\\/12\\\/13\\\/constants-vs-parameterless-functions\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Constants vs. Parameterless Functions\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\",\"name\":\"Philipp Salvisberg&#039;s Blog\",\"description\":\"Database-centric development\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\",\"name\":\"Philipp Salvisberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"width\":400,\"height\":400,\"caption\":\"Philipp Salvisberg\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\"},\"sameAs\":[\"http:\\\/\\\/www.salvis.com\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Constants vs. Parameterless Functions - Philipp Salvisberg&#039;s Blog","description":"Parameterless functions are a way to use constants in SQL outside of PL\/SQL, for example in views. However, they rob the optimizer of the capability to use histograms and therefore finding an optimal execution plan. Actually we can only work around the problem. The Oracle Database has to provide the solution. Either by allowing to access package global constants in SQL (outside of PL\/SQL) or by implementing some kind of peeking for parameterless, deterministic functions.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/","og_locale":"en_US","og_type":"article","og_title":"Constants vs. Parameterless Functions - Philipp Salvisberg&#039;s Blog","og_description":"Parameterless functions are a way to use constants in SQL outside of PL\/SQL, for example in views. However, they rob the optimizer of the capability to use histograms and therefore finding an optimal execution plan. Actually we can only work around the problem. The Oracle Database has to provide the solution. Either by allowing to access package global constants in SQL (outside of PL\/SQL) or by implementing some kind of peeking for parameterless, deterministic functions.","og_url":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/","og_site_name":"Philipp Salvisberg&#039;s Blog","article_published_time":"2019-12-13T17:24:17+00:00","article_modified_time":"2023-11-08T09:55:47+00:00","og_image":[{"width":686,"height":360,"url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan.png","type":"image\/png"}],"author":"Philipp Salvisberg","twitter_card":"summary_large_image","twitter_creator":"@phsalvisberg","twitter_site":"@phsalvisberg","twitter_misc":{"Written by":"Philipp Salvisberg","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/#article","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/"},"author":{"name":"Philipp Salvisberg","@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"headline":"Constants vs. Parameterless Functions","datePublished":"2019-12-13T17:24:17+00:00","dateModified":"2023-11-08T09:55:47+00:00","mainEntityOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/"},"wordCount":1146,"commentCount":4,"publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan.png","keywords":["Performance","PL\/SQL","SQL"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/","url":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/","name":"Constants vs. Parameterless Functions - Philipp Salvisberg&#039;s Blog","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/#primaryimage"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan.png","datePublished":"2019-12-13T17:24:17+00:00","dateModified":"2023-11-08T09:55:47+00:00","description":"Parameterless functions are a way to use constants in SQL outside of PL\/SQL, for example in views. However, they rob the optimizer of the capability to use histograms and therefore finding an optimal execution plan. Actually we can only work around the problem. The Oracle Database has to provide the solution. Either by allowing to access package global constants in SQL (outside of PL\/SQL) or by implementing some kind of peeking for parameterless, deterministic functions.","breadcrumb":{"@id":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/#primaryimage","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan.png","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2019\/12\/bad_execution_plan.png","width":686,"height":360},{"@type":"BreadcrumbList","@id":"https:\/\/www.salvis.com\/blog\/2019\/12\/13\/constants-vs-parameterless-functions\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.salvis.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Constants vs. Parameterless Functions"}]},{"@type":"WebSite","@id":"https:\/\/www.salvis.com\/blog\/#website","url":"https:\/\/www.salvis.com\/blog\/","name":"Philipp Salvisberg&#039;s Blog","description":"Database-centric development","publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.salvis.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515","name":"Philipp Salvisberg","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","width":400,"height":400,"caption":"Philipp Salvisberg"},"logo":{"@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg"},"sameAs":["http:\/\/www.salvis.com\/"]}]}},"_links":{"self":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/9417","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/comments?post=9417"}],"version-history":[{"count":44,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/9417\/revisions"}],"predecessor-version":[{"id":12662,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/9417\/revisions\/12662"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media\/9432"}],"wp:attachment":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media?parent=9417"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/categories?post=9417"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/tags?post=9417"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}