{"id":21867290,"url":"https://github.com/motapinto/sql-query-optimization","last_synced_at":"2025-07-14T01:04:02.075Z","repository":{"id":102320400,"uuid":"341595672","full_name":"motapinto/sql-query-optimization","owner":"motapinto","description":"SQL: Query optimization","archived":false,"fork":false,"pushed_at":"2021-04-17T22:29:37.000Z","size":11419,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-21T21:29:59.542Z","etag":null,"topics":["execution-plan","indexes","oracle-database","query-optimization","report","sql"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/motapinto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-23T15:15:25.000Z","updated_at":"2021-10-24T23:50:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"2dca2d7d-3d58-4092-8503-3965f9939da6","html_url":"https://github.com/motapinto/sql-query-optimization","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/motapinto/sql-query-optimization","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motapinto%2Fsql-query-optimization","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motapinto%2Fsql-query-optimization/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motapinto%2Fsql-query-optimization/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motapinto%2Fsql-query-optimization/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/motapinto","download_url":"https://codeload.github.com/motapinto/sql-query-optimization/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motapinto%2Fsql-query-optimization/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265228873,"owners_count":23731086,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["execution-plan","indexes","oracle-database","query-optimization","report","sql"],"created_at":"2024-11-28T05:09:07.110Z","updated_at":"2025-07-14T01:04:02.043Z","avatar_url":"https://github.com/motapinto.png","language":null,"readme":"# Teaching Service SQL: Query optimization\n\n## Table of Contents\n* [Introduction](#Introduction)\n* [Setting Environment Y](#Setting-Environment-Y)\n    * Primary keys\n    * Foreign keys\n* [Setting Environment Z](#Setting-Environment-Z)\n    * Primary keys\n    * Foreign keys\n    * Indexes\n* [Queries](#Queries)\n    * [Query 1](#Query-1)\n        * SQL Formulation\n        * Result\n        * Execution Plan\n            * Environment X\n            * Environment Y\n            * Environment Z\n        * Conclusion\n    * [Query 2](#Query-2)\n        * SQL Formulation\n        * Result\n        * Execution Plan\n            * Environment X\n            * Environment Y\n            * Environment Z\n        * Conclusion\n    * [Query 3.1](#Query-3.1)\n        * SQL Formulation\n        * Result\n        * Execution Plan\n            * Environment X\n            * Environment Y\n            * Environment Z\n        * Conclusion\n    * [Query 3.2](#Query-3.2)\n        * SQL Formulation\n        * Result\n        * Execution Plan\n            * Environment X\n            * Environment Y\n            * Environment Z\n        * Conclusion\n    * [Query 4](#Query-4)\n        * SQL Formulation\n        * Result\n        * Execution Plan\n            * Environment X\n            * Environment Y\n            * Environment Z\n        * Conclusion\n    * [Query 5](#Query-5)\n        * SQL Formulation\n        * Result\n        * Execution Plan\n            * Environment X\n            * Environment Y\n            * Environment Z\n        * Conclusion\n    * [Query 6](#Query-6)\n        * SQL Formulation\n        * Result\n        * Execution Plan\n            * Environment X\n            * Environment Y\n            * Environment Z\n    * [Conclusion](#Conclusion)\n\n\n\n## Introduction\nThe project consists in the analysis of execution plans for different SQL queries and the evaluation of having different indexes and their impact on the perfomance of those queries.\n\nFor that, we created 3 different environemnts(X, Y and Z).\n* **Environent X** consists of a basic environemnt without any constraints or restrictions.\n* **Environment Y** consists of the same settings present in environment X but includes primary and foreign keys.\n* **Environment Z** consists of the same settings present in environment Y but also include indexes.\n\n**NOTE:** You can populate the database by using the scripts in populate/\n\n## Setting Environment Y\n###### *Shortcut:* \u003cins\u003e[To the top](#Table-of-Contents)\u003c/ins\u003e\n### Primary keys\n```sql\nALTER TABLE \"YDOCENTES\" \n    ADD CONSTRAINT YDOCENTES_PKEY \n    PRIMARY KEY(\"NR\");\n    \nALTER TABLE \"YDSD\" \n    ADD CONSTRAINT YDSD_PKEY \n    PRIMARY KEY(\"NR\", \"ID\");\n    \nALTER TABLE \"YTIPOSAULA\" \n    ADD CONSTRAINT YTIPOSAULA_PKEY \n    PRIMARY KEY(\"ID\");\n\nALTER TABLE \"YOCORRENCIAS\" \n    ADD CONSTRAINT YOCORRENCIAS_PKEY \n    PRIMARY KEY(\"CODIGO\", \"ANO_LETIVO\", \"PERIODO\");\n    \nALTER TABLE \"YUCS\" \n    ADD CONSTRAINT YUCS_PKEY \n    PRIMARY KEY(\"CODIGO\");\n```\n### Foreign keys\n```sql\nALTER TABLE \"YDSD\" \n    ADD CONSTRAINT YDSD_FKEY_YDOCENTES \n    FOREIGN KEY(\"NR\") \n    REFERENCES \"YDOCENTES\"(\"NR\");\n    \nALTER TABLE \"YDSD\" \n    ADD CONSTRAINT YDSD_FKEY_YTIPOSAULA \n    FOREIGN KEY(\"ID\") \n    REFERENCES \"YTIPOSAULA\"(\"ID\");\n    \nALTER TABLE \"YOCORRENCIAS\" \n    ADD CONSTRAINT YOCORRENCIAS_FKEY_YUCS \n    FOREIGN KEY(\"CODIGO\") \n    REFERENCES \"YUCS\"(\"CODIGO\");\n\nALTER TABLE \"YTIPOSAULA\" \n    ADD CONSTRAINT YTIPOSAULA_FKEY_YOCORRENCIAS\n    FOREIGN KEY(\"CODIGO\", \"ANO_LETIVO\", \"PERIODO\") \n    REFERENCES \"YOCORRENCIAS\"(\"CODIGO\", \"ANO_LETIVO\", \"PERIODO\");\n```\n## Setting Environment Z\n###### *Shortcut:* \u003cins\u003e[To the top](#Table-of-Contents)\u003c/ins\u003e\n### Primary keys\n```sql\nALTER TABLE \"ZDOCENTES\" \n    ADD CONSTRAINT ZDOCENTES_PKEY \n    PRIMARY KEY(\"NR\");\n    \nALTER TABLE \"ZDSD\" \n    ADD CONSTRAINT ZDSD_PKEY \n    PRIMARY KEY(\"NR\", \"ID\");\n    \nALTER TABLE \"ZTIPOSAULA\" \n    ADD CONSTRAINT ZTIPOSAULA_PKEY \n    PRIMARY KEY(\"ID\");\n\nALTER TABLE \"ZOCORRENCIAS\" \n    ADD CONSTRAINT ZOCORRENCIAS_PKEY \n    PRIMARY KEY(\"CODIGO\", \"ANO_LETIVO\", \"PERIODO\");\n    \nALTER TABLE \"ZUCS\" \n    ADD CONSTRAINT ZUCS_PKEY \n    PRIMARY KEY(\"CODIGO\");\n```\n### Foreign keys\n```sql\nALTER TABLE \"ZDSD\" \n    ADD CONSTRAINT ZDSD_FKEY_ZDOCENTES \n    FOREIGN KEY(\"NR\") \n    REFERENCES \"ZDOCENTES\"(\"NR\");\n    \nALTER TABLE \"ZDSD\" \n    ADD CONSTRAINT ZDSD_FKEY_ZTIPOSAULA \n    FOREIGN KEY(\"ID\") \n    REFERENCES \"ZTIPOSAULA\"(\"ID\");\n    \nALTER TABLE \"ZOCORRENCIAS\" \n    ADD CONSTRAINT ZOCORRENCIAS_FKEY_ZUCS \n    FOREIGN KEY(\"CODIGO\") \n    REFERENCES \"ZUCS\"(\"CODIGO\");\n\nALTER TABLE \"ZTIPOSAULA\" \n    ADD CONSTRAINT ZTIPOSAULA_FKEY_ZOCORRENCIAS\n    FOREIGN KEY(\"CODIGO\", \"ANO_LETIVO\", \"PERIODO\") \n    REFERENCES \"ZOCORRENCIAS\"(\"CODIGO\", \"ANO_LETIVO\", \"PERIODO\");\n```\n\n### Indexes\nOne of the things that can most improve query times is to add indexes to **foreign keys**, when this is not done automatically. Furthermore, columns that are used in complex **joins**, in **where** conditions should also be considered.\n\nTo determine the most appropriate index type we had in consideration the types of queries. Since all of them are ***SELECT*** conditions, it obviously had a considerable weight in our decisions.\n\n```sql\nCREATE INDEX IX_ZUCS_DESIGNACAO ON ZUCS (designacao);\nCREATE INDEX IX_ZUCS_CODIGO_CURSO ON ZUCS(codigo, curso);\nCREATE INDEX IX_ZUCS_CURSO ON ZUCS (curso DESC);\nCREATE INDEX IX_ZTIPOSAULA_ANOLETIVO ON ZTIPOSAULA (ano_letivo DESC);\nCREATE INDEX IX_ZTIPOSAULA_CODIGO ON ZTIPOSAULA(codigo);\nCREATE INDEX IX_ZTIPOSAULA_TIPO ON ZTIPOSAULA (tipo);\nCREATE INDEX IX_ZDSD_ID ON ZDSD(id);\n```\n\n**Note:** All indexes will be justified for each query. Here is just a demonstration of all indexes.\n\n## Queries\n### Query 1\n###### *Shortcut:* \u003cins\u003e[To the top](#Table-of-Contents)\u003c/ins\u003e\n**Show the codigo, designacao, ano_letivo, inscritos, tipo, and turnos for the course ‘Bases de Dados’ of the program 275.**\n#### SQL Formulation\n```sql\nSELECT codigo, designacao, ano_letivo, inscritos, tipo, turnos\nFROM XUCS UCS \nJOIN XOCORRENCIAS OCCURENCES USING (codigo)\nJOIN XTIPOSAULA CLASSTYPES USING (codigo, periodo, ano_letivo)\nWHERE UCS.curso = 275 AND UCS.designacao = 'Bases de Dados'\n```\n\n#### Result (in JSON format)\n```json\n{\n  \"results\" : [\n    {\n      \"columns\" : [\n        {\n          \"name\" : \"CODIGO\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"ANO_LETIVO\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"DESIGNACAO\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"INSCRITOS\",\n          \"type\" : \"NUMBER\"\n        },\n        {\n          \"name\" : \"TIPO\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"TURNOS\",\n          \"type\" : \"NUMBER\"\n        }\n      ],\n      \"items\" : [\n        {\n          \"codigo\" : \"EIC3106\",\n          \"ano_letivo\" : \"2003/2004\",\n          \"designacao\" : \"Bases de Dados\",\n          \"inscritos\" : 92,\n          \"tipo\" : \"T\",\n          \"turnos\" : 1\n        },\n        {\n          \"codigo\" : \"EIC3106\",\n          \"ano_letivo\" : \"2003/2004\",\n          \"designacao\" : \"Bases de Dados\",\n          \"inscritos\" : 92,\n          \"tipo\" : \"TP\",\n          \"turnos\" : 4\n        },\n        {\n          \"codigo\" : \"EIC3106\",\n          \"ano_letivo\" : \"2004/2005\",\n          \"designacao\" : \"Bases de Dados\",\n          \"inscritos\" : 114,\n          \"tipo\" : \"T\",\n          \"turnos\" : 1\n        },\n        {\n          \"codigo\" : \"EIC3106\",\n          \"ano_letivo\" : \"2004/2005\",\n          \"designacao\" : \"Bases de Dados\",\n          \"inscritos\" : 114,\n          \"tipo\" : \"TP\",\n          \"turnos\" : 4\n        },\n        {\n          \"codigo\" : \"EIC3111\",\n          \"ano_letivo\" : \"2005/2006\",\n          \"designacao\" : \"Bases de Dados\",\n          \"inscritos\" : \"\",\n          \"tipo\" : \"T\",\n          \"turnos\" : 1\n        },\n        {\n          \"codigo\" : \"EIC3111\",\n          \"ano_letivo\" : \"2005/2006\",\n          \"designacao\" : \"Bases de Dados\",\n          \"inscritos\" : \"\",\n          \"tipo\" : \"TP\",\n          \"turnos\" : 6\n        }\n      ]\n    }\n  ]\n}\n```\n#### Execution Plan\n|           | Environment X | Environment Y | Environment Z |\n| --------- | ------------- | ------------- | ------------- |\n| Cost      |   642         |   55          |     14        |\n\n##### Environment X\n![](https://i.imgur.com/ZxZJu4m.png)\n-\n##### Environment Y\nSince in this query there are two expensive join operations and a where clause, we can see that using primary and foreign keys have a great impact on the cost of the query.\n\n![](https://i.imgur.com/FdvOZhy.png)\n-\n##### Environment Z\nThis are the indexes used to improve the cost of the query. It was also used the constraints defined from the previous environment. \n```sql\nCREATE INDEX IX_ZUCS_DESIGNACAO ON ZUCS (designacao);\nCREATE INDEX IX_ZTIPOSAULA_CODIGO ON ZTIPOSAULA(codigo);\nCREATE INDEX IX_ZUCS_CODIGO_CURSO ON ZUCS(codigo, curso);\n```\nThe first and the second one are useful since the **curso** and **designacao** columns from **ZUCS** are used in the **WHERE** condition to get a UC from a specific degree with a specific designation.\n\nThe third one is also very useful because it reduces the cost of the **hash joins** operations. It uses a composite index with the columns **codigo** and **curso**.\n\n![](https://i.imgur.com/JKC4Zl3.png)\n\n\n---\n### Query 2\n###### *Shortcut:* \u003cins\u003e[To the top](#Table-of-Contents)\u003c/ins\u003e\n**How many class hours of each type did the program 233 planned in year 2004/2005?**\n#### SQL Formulation\n```sql\nSELECT DISTINCT UCS.curso, CLASS_TYPES.ano_letivo, CLASS_TYPES.tipo, \n    SUM(CLASS_TYPES.turnos * CLASS_TYPES.horas_turno) AS TOTAL_HOURS\nFROM XTIPOSAULA CLASS_TYPES \nINNER JOIN XUCS UCS ON CLASS_TYPES.codigo = UCS.codigo\nWHERE CLASS_TYPES.ano_letivo='2004/2005' \n    AND UCS.curso = '233'\nGROUP BY  UCS.curso, CLASS_TYPES.ano_letivo, CLASS_TYPES.tipo;\n```\n\n#### Result (in JSON format)\n```json\n{\n  \"results\" : [\n    {\n      \"columns\" : [\n        {\n          \"name\" : \"CURSO\",\n          \"type\" : \"NUMBER\"\n        },\n        {\n          \"name\" : \"ANO_LETIVO\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"TIPO\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"TOTAL_HOURS\",\n          \"type\" : \"NUMBER\"\n        }\n      ],\n      \"items\" : [\n        {\n          \"curso\" : 233,\n          \"ano_letivo\" : \"2004/2005\",\n          \"tipo\" : \"TP\",\n          \"total_hours\" : 697.5\n        },\n        {\n          \"curso\" : 233,\n          \"ano_letivo\" : \"2004/2005\",\n          \"tipo\" : \"P\",\n          \"total_hours\" : 581.5\n        },\n        {\n          \"curso\" : 233,\n          \"ano_letivo\" : \"2004/2005\",\n          \"tipo\" : \"T\",\n          \"total_hours\" : 308\n        }\n      ]\n    }\n  ]\n}\n```\n#### Execution Plan\n|           | Environment X | Environment Y | Environment Z |\n| --------- | ------------- | ------------- | ------------- |\n| Cost      |       50      |       50      |       10      |\n\n##### Environment X\n![](https://i.imgur.com/MYe0ihm.png)\n##### Environment Y\nCompared to environment X, primary and foreign key constraints didn't have any impact on the cost of the query.\n\n![](https://i.imgur.com/ce9DCBu.png)\n##### Environment Z\n\nThese are the indexes used to improve the cost of the query. Additionally, the constraints defined from the previous environment were also used. \n\n```sql\nCREATE INDEX IX_ZUCS_CURSO ON ZUCS (curso DESC);\nCREATE INDEX IX_ZTIPOSAULA_ANOLETIVO ON ZTIPOSAULA (ano_letivo DESC);\n```\n\nBoth indexes are useful since the **curso** column from **ZUCS** and **ano_letivo** column from **ZTIPOSAULA** are used in the **WHERE** condition to retrieve a specific program from a specific year.\n\n![](https://i.imgur.com/wLTXvzS.png)\n\n---\n### Query 3.1\n###### *Shortcut:* \u003cins\u003e[To the top](#Table-of-Contents)\u003c/ins\u003e\n**Which courses did have occurrences planned but did not get service assigned in year 2003/2004?***[Using NOT IN]*\n#### SQL Formulation\n```sql\nSELECT DISTINCT UCS.codigo\nFROM XOCORRENCIAS OCCURENCES\nINNER JOIN XUCS UCS ON OCCURENCES.codigo = UCS.codigo \nWHERE OCCURENCES.ano_letivo = '2003/2004'\n    AND UCS.codigo NOT IN (\n        SELECT DISTINCT codigo\n        FROM XTIPOSAULA CLASS_TYPES\n        INNER JOIN XDSD T_DISTRIBUTION ON CLASS_TYPES.id = T_DISTRIBUTION.id\n        WHERE CLASS_TYPES.ano_letivo = '2003/2004'  \n     )\n```\n\nThere was also a try to have a materialized view for a portion of the query using the following DDL statement\n```sql\nCREATE MATERIALIZED VIEW \nPLANNED_UCS AS \nSELECT DISTINCT codigo\nFROM XTIPOSAULA CLASS_TYPES\nINNER JOIN XDSD T_DISTRIBUTION ON CLASS_TYPES.id = T_DISTRIBUTION.id\nWHERE CLASS_TYPES.ano_letivo = '2003/2004';\n```\n\n```sql\nSELECT DISTINCT UCS.codigo\nFROM XOCORRENCIAS OCCURENCES\nINNER JOIN XUCS UCS ON OCCURENCES.codigo = UCS.codigo \nWHERE OCCURENCES.ano_letivo = '2003/2004'\n    AND NOT EXISTS  (\n        SELECT codigo\n        FROM PLANNED_UCS\n        WHERE codigo = OCCURENCES.codigo\n    )\n```\n\n#### Result (in JSON format)\n* *138 row*\n```json\n{\n  \"results\" : [\n    {\n      \"columns\" : [\n        {\n          \"name\" : \"CODIGO\",\n          \"type\" : \"VARCHAR2\"\n        }\n      ],\n      \"items\" : [\n        {\n          \"codigo\" : \"MEMT1000\"\n        },\n        {\n          \"codigo\" : \"MEMT100\"\n        },\n        {\n          \"codigo\" : \"EQ418\"\n        },\n        {\n          \"codigo\" : \"MTM108\"\n        },\n        {\n          \"codigo\" : \"MEMT131\"\n        },\n        {\n          \"codigo\" : \"MEEC1053\"\n        },\n        {\n          \"codigo\" : \"MEM157\"\n        },\n        {\n          \"codigo\" : \"MEM181\"\n        },\n        {\n          \"codigo\" : \"MDI1205\"\n        },\n        {\n          \"codigo\" : \"MPFCA103\"\n        },\n        {\n          \"codigo\" : \"MPFCA204\"\n        },\n        {\n          \"codigo\" : \"EIC4220\"\n        },\n        {\n          \"codigo\" : \"EIC4221\"\n        },\n        {\n          \"codigo\" : \"EIC4222\"\n        },\n        {\n          \"codigo\" : \"CI027\"\n        },\n        {\n          \"codigo\" : \"MEMT107\"\n        },\n        {\n          \"codigo\" : \"MEMT102\"\n        },\n        {\n          \"codigo\" : \"MEAM1310\"\n        },\n        {\n          \"codigo\" : \"MPPAU2215\"\n        },\n        {\n          \"codigo\" : \"MEM187\"\n        },\n        {\n          \"codigo\" : \"MEM189\"\n        },\n        {\n          \"codigo\" : \"MEA219\"\n        },\n        {\n          \"codigo\" : \"EI1107\"\n        },\n        {\n          \"codigo\" : \"MPFCA106\"\n        },\n        {\n          \"codigo\" : \"EIC4225\"\n        },\n        {\n          \"codigo\" : \"CI014\"\n        },\n        {\n          \"codigo\" : \"CI018\"\n        },\n        {\n          \"codigo\" : \"CI007\"\n        },\n        {\n          \"codigo\" : \"CI017\"\n        },\n        {\n          \"codigo\" : \"CI008\"\n        },\n        {\n          \"codigo\" : \"MEA412\"\n        },\n        {\n          \"codigo\" : \"MTM111\"\n        },\n        {\n          \"codigo\" : \"MDI1105\"\n        },\n        {\n          \"codigo\" : \"MDI1103\"\n        },\n        {\n          \"codigo\" : \"MEMT2000\"\n        },\n        {\n          \"codigo\" : \"MEAM1312\"\n        },\n        {\n          \"codigo\" : \"MEMT135\"\n        },\n        {\n          \"codigo\" : \"MPPAU1113\"\n        },\n        {\n          \"codigo\" : \"EIC3209\"\n        },\n        {\n          \"codigo\" : \"MEM179\"\n        },\n        {\n          \"codigo\" : \"MEA215\"\n        },\n        {\n          \"codigo\" : \"MEA414\"\n        },\n        {\n          \"codigo\" : \"MDI1107\"\n        },\n        {\n          \"codigo\" : \"MDI1208\"\n        },\n        {\n          \"codigo\" : \"MDI1108\"\n        },\n        {\n          \"codigo\" : \"MPPAU2217\"\n        },\n        {\n          \"codigo\" : \"MPFCA101\"\n        },\n        {\n          \"codigo\" : \"MPFCA205\"\n        },\n        {\n          \"codigo\" : \"EIC5127\"\n        },\n        {\n          \"codigo\" : \"MTM115\"\n        },\n        {\n          \"codigo\" : \"EMM528\"\n        },\n        {\n          \"codigo\" : \"MTM110\"\n        },\n        {\n          \"codigo\" : \"MEAM5000\"\n        },\n        {\n          \"codigo\" : \"EC5280\"\n        },\n        {\n          \"codigo\" : \"MPFCA100\"\n        },\n        {\n          \"codigo\" : \"MPFCA104\"\n        },\n        {\n          \"codigo\" : \"MPFCA200\"\n        },\n        {\n          \"codigo\" : \"EC5200\"\n        },\n        {\n          \"codigo\" : \"EEC5022\"\n        },\n        {\n          \"codigo\" : \"EIC5124\"\n        },\n        {\n          \"codigo\" : \"CI020\"\n        },\n        {\n          \"codigo\" : \"CI016\"\n        },\n        {\n          \"codigo\" : \"CI011\"\n        },\n        {\n          \"codigo\" : \"MTM114\"\n        },\n        {\n          \"codigo\" : \"MPPAU1114\"\n        },\n        {\n          \"codigo\" : \"MEM180\"\n        },\n        {\n          \"codigo\" : \"MVC1211\"\n        },\n        {\n          \"codigo\" : \"MEA112\"\n        },\n        {\n          \"codigo\" : \"MEA217\"\n        },\n        {\n          \"codigo\" : \"MEA320\"\n        },\n        {\n          \"codigo\" : \"MEMT106\"\n        },\n        {\n          \"codigo\" : \"EC5287\"\n        },\n        {\n          \"codigo\" : \"MDI1106\"\n        },\n        {\n          \"codigo\" : \"MPPAU2219\"\n        },\n        {\n          \"codigo\" : \"MPFCA105\"\n        },\n        {\n          \"codigo\" : \"MPFCA107\"\n        },\n        {\n          \"codigo\" : \"MPFCA201\"\n        },\n        {\n          \"codigo\" : \"MPFCA202\"\n        },\n        {\n          \"codigo\" : \"MPFCA206\"\n        },\n        {\n          \"codigo\" : \"EIC5125\"\n        },\n        {\n          \"codigo\" : \"EIC5126\"\n        },\n        {\n          \"codigo\" : \"CI038\"\n        },\n        {\n          \"codigo\" : \"MEB205\"\n        },\n        {\n          \"codigo\" : \"EQ407\"\n        },\n        {\n          \"codigo\" : \"MDI1204\"\n        },\n        {\n          \"codigo\" : \"MDI1100\"\n        },\n        {\n          \"codigo\" : \"MFAMF1108\"\n        },\n        {\n          \"codigo\" : \"MPPAU2220\"\n        },\n        {\n          \"codigo\" : \"MPPAU2216\"\n        },\n        {\n          \"codigo\" : \"MEM163\"\n        },\n        {\n          \"codigo\" : \"MEM175\"\n        },\n        {\n          \"codigo\" : \"MEM184\"\n        },\n        {\n          \"codigo\" : \"MEM188\"\n        },\n        {\n          \"codigo\" : \"MEM191\"\n        },\n        {\n          \"codigo\" : \"MEA415\"\n        },\n        {\n          \"codigo\" : \"EIC4223\"\n        },\n        {\n          \"codigo\" : \"EIC5122\"\n        },\n        {\n          \"codigo\" : \"EIC5123\"\n        },\n        {\n          \"codigo\" : \"CI023\"\n        },\n        {\n          \"codigo\" : \"CI009\"\n        },\n        {\n          \"codigo\" : \"MEM1205\"\n        },\n        {\n          \"codigo\" : \"GEI512\"\n        },\n        {\n          \"codigo\" : \"MEMT105\"\n        },\n        {\n          \"codigo\" : \"MTM104\"\n        },\n        {\n          \"codigo\" : \"MEAM1314\"\n        },\n        {\n          \"codigo\" : \"EQ411\"\n        },\n        {\n          \"codigo\" : \"MDI1207\"\n        },\n        {\n          \"codigo\" : \"MDI1209\"\n        },\n        {\n          \"codigo\" : \"MEB204\"\n        },\n        {\n          \"codigo\" : \"MMCCE1220\"\n        },\n        {\n          \"codigo\" : \"EEC2207\"\n        },\n        {\n          \"codigo\" : \"EIC4224\"\n        },\n        {\n          \"codigo\" : \"EIC5129\"\n        },\n        {\n          \"codigo\" : \"CI019\"\n        },\n        {\n          \"codigo\" : \"CI002\"\n        },\n        {\n          \"codigo\" : \"CI025\"\n        },\n        {\n          \"codigo\" : \"CI037\"\n        },\n        {\n          \"codigo\" : \"MEB105\"\n        },\n        {\n          \"codigo\" : \"EQ308\"\n        },\n        {\n          \"codigo\" : \"MPPAU2218\"\n        },\n        {\n          \"codigo\" : \"MPPAU1112\"\n        },\n        {\n          \"codigo\" : \"EEC5272\"\n        },\n        {\n          \"codigo\" : \"MEM5000\"\n        },\n        {\n          \"codigo\" : \"MEM158\"\n        },\n        {\n          \"codigo\" : \"MEM182\"\n        },\n        {\n          \"codigo\" : \"MEM183\"\n        },\n        {\n          \"codigo\" : \"MEA216\"\n        },\n        {\n          \"codigo\" : \"MEA319\"\n        },\n        {\n          \"codigo\" : \"MEST210\"\n        },\n        {\n          \"codigo\" : \"MEMT110\"\n        },\n        {\n          \"codigo\" : \"MDI1206\"\n        },\n        {\n          \"codigo\" : \"MEMT120\"\n        },\n        {\n          \"codigo\" : \"MPPAU1115\"\n        },\n        {\n          \"codigo\" : \"MPFCA102\"\n        },\n        {\n          \"codigo\" : \"MPFCA203\"\n        },\n        {\n          \"codigo\" : \"CI003\"\n        },\n        {\n          \"codigo\" : \"CI004\"\n        },\n        {\n          \"codigo\" : \"CI013\"\n        }\n      ]\n    }\n  ]\n}\n```\n#### Execution Plan\n|           | Environment X | Environment Y | Environment Z |\n| --------- | ------------- | ------------- | ------------- |\n| Cost without Mat. View     |      670      |      86       |      51       |\n| Cost with Mat. View      |      610      |      31       |      31       |\n\n\n##### Environment X\nWithout the materialized view:\n![](https://i.imgur.com/tMCBKS6.png)\n\nWith the materialized view:\n![](https://i.imgur.com/ovqITw3.png)\n\n##### Environment Y\nCompared to environment X, primary and foreign key constraints had a great impact on the query performance. This can be seen in the query plan where it's used a fast full scan twice in the query.\n\nWithout the materialized view:\n![](https://i.imgur.com/UU6W6pH.png)\n\nWith the materialized view:\n![](https://i.imgur.com/ZtuEUGW.png)\n\n##### Environment Z\nThis are the indexes used to improve the cost of the query. It was also used the constraints defined from the previous environment. \n```sql\nCREATE INDEX IX_ZTIPOSAULA_ANOLETIVO ON ZTIPOSAULA (ano_letivo DESC);\nCREATE INDEX IX_ZDSD_ID ON ZDSD(id);\n```\nThe first one is useful since the **ano_letivo** column from **ZTIPOSAULA** is used in the **WHERE** condition to determine the planned ucs. We could also opt to create the index on all attribute from the foreign key but that would produce the same effect.\n\nThe second one is also useful because the **primary key** on **ZDSD** is (nr, id) that creates a composite index on both attributes. The problem is that the composite index will work on statements that use only NR or both the nr and id columns. Since the **id** is used for the **JOIN** operation, that index also as an impact on the query cost.\n\nWithout the materialized view:\n![](https://i.imgur.com/NStzLWm.png)\n\nWith the materialized view:\n![](https://i.imgur.com/VG4bI7a.png)\n\n---\n### Query 3.2\n###### *Shortcut:* \u003cins\u003e[To the top](#Table-of-Contents)\u003c/ins\u003e\n\n**Which courses did have occurrences planned but did not get service assigned in year 2003/2004?** *[Using external join and is null]*\n#### SQL Formulation\n```sql\nSELECT DISTINCT UCS.codigo\nFROM XOCORRENCIAS OCCURENCES\nINNER JOIN XUCS UCS ON OCCURENCES.codigo = UCS.codigo\nLEFT OUTER JOIN (\n    SELECT DISTINCT codigo\n    FROM XTIPOSAULA CLASS_TYPES\n    INNER JOIN XDSD T_DISTRIBUTION ON CLASS_TYPES.id = T_DISTRIBUTION.id\n    WHERE CLASS_TYPES.ano_letivo = '2003/2004'\n) PLANNED_UCS ON PLANNED_UCS.codigo = UCS.codigo\nWHERE PLANNED_UCS.CODIGO IS NULL \n    AND ANO_LETIVO = '2003/2004'\n```\n\n#### Result (in JSON format)\n* The same result as in [Query 3.1](#Query-3.1)\n#### Execution Plan\n|           | Environment X | Environment Y | Environment Z |\n| --------- | ------------- | ------------- | ------------- |\n| Cost      |      671      |      87       |       52      |\n\n##### Environment X\n![](https://i.imgur.com/erJTuaF.png)\n##### Environment Y\nCompared to environment X, primary and foreign key constraints didn't have any impact on the cost of the query since the access done was a full access.\n![](https://i.imgur.com/BbyqtbR.png)\n##### Environment Z\n* The same indexes were used as in [Query 3.1](#Query-3.1)\n\n![](https://i.imgur.com/wNx4sWX.png)\n\n---\n### Query 4\n###### *Shortcut:* \u003cins\u003e[To the top](#Table-of-Contents)\u003c/ins\u003e\n**Who is the professor with more class hours for each type of class, in the academic year 2003/2004? \nShow the number and name of the professor, the type of class and the total of class hours times the factor.**\n\n\n#### SQL Formulation\n```sql\nSELECT nr, nome, tipo, max_hours\nFROM  (\n    SELECT MAX(nr) AS nr, tipo, MAX(total_hours) AS max_hours\n    FROM (\n        SELECT nr, tipo, SUM(horas * fator) AS total_hours\n        FROM XTIPOSAULA\n        NATURAL JOIN XDSD \n        WHERE ano_letivo = '2003/2004'\n        GROUP BY nr, tipo\n    )\n    GROUP BY TIPO\n) TMP\nNATURAL JOIN XDOCENTES \n```\n\n\n#### Result (in JSON format)\n```json\n{\n  \"results\" : [\n    {\n      \"columns\" : [\n        {\n          \"name\" : \"NR\",\n          \"type\" : \"NUMBER\"\n        },\n        {\n          \"name\" : \"NOME\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"TIPO\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"MAX_HOURS\",\n          \"type\" : \"NUMBER\"\n        }\n      ],\n      \"items\" : [\n        {\n          \"nr\" : 246626,\n          \"nome\" : \"Jorge Manuel Gomes Barbosa\",\n          \"tipo\" : \"OT\",\n          \"max_hours\" : 3.5\n        },\n        {\n          \"nr\" : 908100,\n          \"nome\" : \"Armínio de Almeida Teixeira\",\n          \"tipo\" : \"P\",\n          \"max_hours\" : 30\n        },\n        {\n          \"nr\" : 908290,\n          \"nome\" : \"José Manuel Miguez Araújo\",\n          \"tipo\" : \"TP\",\n          \"max_hours\" : 26\n        },\n        {\n          \"nr\" : 909330,\n          \"nome\" : \"Nuno Filipe da Cunha Nogueira\",\n          \"tipo\" : \"T\",\n          \"max_hours\" : 30.67\n        }\n      ]\n    }\n  ]\n}\n```\n#### Execution Plan\n|           | Environment X | Environment Y | Environment Z |\n| --------- | ------------- | ------------- | ------------- |\n| Cost      |      69       |      69       |      38       |\n\n##### Environment X\n![](https://i.imgur.com/t8eEMEW.png)\n\n##### Environment Y\nCompared to environment X, primary and foreign key constraints didn't have any impact on the cost of the query.\n\n![](https://i.imgur.com/8niDVsA.png)\n\n##### Environment Z\nOnly one index was used to  improve the cost of the query. Additionally, the constraints defined from the previous environment were also used. \n\n```sql\nCREATE INDEX IX_ZTIPOSAULA_ANOLETIVO ON ZTIPOSAULA (ano_letivo DESC);\n```\n\nThis index is useful since the **ano_letivo** column from **ZTIPOSAULA** is used in the **WHERE** condition to retrieve a specific year.\n\n![](https://i.imgur.com/UGzvPq9.png)\n\n\n---\n### Query 5\n###### *Shortcut:* \u003cins\u003e[To the top](#Table-of-Contents)\u003c/ins\u003e\n\n**Compare the execution plans (just the environment Z) and the index sizes for the query giving the course code, the academic year, the period, and number of hours of the type ‘OT’ in the academic years of 2002/2003 and 2003/2004.**\n\n* a) With a B-tree index on the type and academic year columns of the\nZTIPOSAULA table;\n* b) With a bitmap index on the type and academic year columns of the\nZTIPOSAULA table;\n\n#### B-tree index\n* High cardinality\n```sql\nCREATE INDEX IX_ZTIPOSAULA_TIPO ON ZTIPOSAULA (TIPO);\nCREATE INDEX IX_ZTIPOSAULA_ANOLETIVO ON ZTIPOSAULA (ANO_LETIVO DESC);\n```\n\n#### Bitmap index\n* Low cardinality \n\n```sql\nCREATE BITMAP INDEX IX_ZTIPOSAULA_TIPO ON ZTIPOSAULA (TIPO);\nCREATE BITMAP INDEX IX_ZTIPOSAULA_ANOLETIVO ON ZTIPOSAULA (ANO_LETIVO DESC);\n```\n#### SQL Formulation\n```sql\nSELECT codigo, ano_letivo, periodo, horas_turno * turnos as NumberOfHours\nFROM ZTIPOSAULA\nWHERE (ano_letivo = '2002/2003' OR ano_letivo = '2003/2004') AND (tipo = 'OT')\n```\n\n#### Result (in JSON format)\n```json\n{\n  \"results\" : [\n    {\n      \"columns\" : [\n        {\n          \"name\" : \"CODIGO\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"ANO_LETIVO\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"PERIODO\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"NUMBEROFHOURS\",\n          \"type\" : \"NUMBER\"\n        }\n      ],\n      \"items\" : [\n        {\n          \"codigo\" : \"EIC5202\",\n          \"ano_letivo\" : \"2002/2003\",\n          \"periodo\" : \"2S\",\n          \"numberofhours\" : 27\n        },\n        {\n          \"codigo\" : \"EIC5202\",\n          \"ano_letivo\" : \"2003/2004\",\n          \"periodo\" : \"2S\",\n          \"numberofhours\" : 24\n        }\n      ]\n    }\n  ]\n}\n```\n\n#### Execution Plan\n|                  | Environment Z a) | Environment Z b) |\n| ---------------- | ---------------- | ---------------- |\n| Cost             |        5         |        8        | \n\n\n##### Environment Z a)\n![](https://i.imgur.com/KzE05Wv.png)\n\nIn Oracle, full table scans have less cost than index range scans in cases when accessing a large fraction of the blocks in a table. The reason is that full table scans can use larger I/O calls what is cheaper than making many smaller calls.\n\nBut, Oracle optimizer uses a **range scan** when it finds one or more leading columns of an index specified in condition as it is in this task.\n\n##### Environment Z b)\n![](https://i.imgur.com/PtygCxP.png)\n\nThe way of accessing the attributes is similar to the one on the execution with the B-tree index, using an index access and a table access by index rowid, however, the query has a higher cost when executed with a bitmap index.\n\n#### Index sizes\n* Query to get index sizes:\n```sql\nSELECT  index_name, index_type, table_name, uniqueness, blevel, leaf_blocks, distinct_keys, num_rows\nFROM user_indexes;\n```\n![](https://i.imgur.com/g367kMB.png)\n\n\n#### Result (in JSON format) - B-tree indexes\n```json\n{\n  \"results\" : [\n    {\n      \"columns\" : [\n        {\n          \"name\" : \"INDEX_NAME\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"INDEX_TYPE\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"TABLE_NAME\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"UNIQUENESS\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"BLEVEL\",\n          \"type\" : \"NUMBER\"\n        },\n        {\n          \"name\" : \"LEAF_BLOCKS\",\n          \"type\" : \"NUMBER\"\n        },\n        {\n          \"name\" : \"DISTINCT_KEYS\",\n          \"type\" : \"NUMBER\"\n        },\n        {\n          \"name\" : \"NUM_ROWS\",\n          \"type\" : \"NUMBER\"\n        }\n      ],\n      \"items\" : [\n        {\n        \"index_name\" : \"IX_ZTIPOSAULA_TIPO\",\n          \"index_type\" : \"NORMAL\",\n          \"table_name\" : \"ZTIPOSAULA\",\n          \"uniqueness\" : \"NONUNIQUE\",\n          \"blevel\" : 1,\n          \"leaf_blocks\" : 39,\n          \"distinct_keys\" : 5,\n          \"num_rows\" : 21019\n        },\n        {\n          \"index_name\" : \"IX_ZTIPOSAULA_ANOLETIVO\",\n          \"index_type\" : \"FUNCTION-BASED NORMAL\",\n          \"table_name\" : \"ZTIPOSAULA\",\n          \"uniqueness\" : \"NONUNIQUE\",\n          \"blevel\" : 1,\n          \"leaf_blocks\" : 65,\n          \"distinct_keys\" : 19,\n          \"num_rows\" : 21019\n        }\n      ]\n    }\n  ]\n}\n\n```\n#### Result (in JSON format) - Bitmap indexes\nUnder is showed part of JSON regarding indexes from task 5.\n```json\n{\n  \"results\" : [\n    {\n      \"columns\" : [\n        {\n          \"name\" : \"INDEX_NAME\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"INDEX_TYPE\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"TABLE_NAME\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"UNIQUENESS\",\n          \"type\" : \"VARCHAR2\"\n        },\n        {\n          \"name\" : \"BLEVEL\",\n          \"type\" : \"NUMBER\"\n        },\n        {\n          \"name\" : \"LEAF_BLOCKS\",\n          \"type\" : \"NUMBER\"\n        },\n        {\n          \"name\" : \"DISTINCT_KEYS\",\n          \"type\" : \"NUMBER\"\n        },\n        {\n          \"name\" : \"NUM_ROWS\",\n          \"type\" : \"NUMBER\"\n        }\n      ],\n      \"items\" : [\n        {\n          \"index_name\" : \"IX_ZTIPOSAULA_ANOLETIVO\",\n          \"index_type\" : \"BITMAP\",\n          \"table_name\" : \"ZTIPOSAULA\",\n          \"uniqueness\" : \"NONUNIQUE\",\n          \"blevel\" : 0,\n          \"leaf_blocks\" : 1,\n          \"distinct_keys\" : 19,\n          \"num_rows\" : 19\n        },\n        {\n          \"index_name\" : \"IX_ZTIPOSAULA_TIPO\",\n          \"index_type\" : \"BITMAP\",\n          \"table_name\" : \"ZTIPOSAULA\",\n          \"uniqueness\" : \"NONUNIQUE\",\n          \"blevel\" : 1,\n          \"leaf_blocks\" : 2,\n          \"distinct_keys\" : 5,\n          \"num_rows\" : 5\n        }\n      ]\n    }\n  ]\n}\n\n```\nTwo columns that are important to look at are: \"leaf_blocks\" as the number of blocks used by the index at the lowest and largest level, and \"num_rows\" as the number of rows that are indexed.\n\nLooking at the given JSON results above for both indexes we can compare \"leaf_blocks\" values. If the \"leaf_blocks\" values is lager that means index consumes more space. It is visible that bitmap indexes need drastically less space than their B-tree equivalents. Also, with B-tree index we have one entry in the \"leaf_blocks\" for each row in the table but with Bitmap index no. \n\nIf we take a look at the \"num_rows\" we can see that bitmap indexes also have significantly smaller value than b-tree indexes. The reason is because bitmap indexes store a single key value that points to many rows and because of that, there will be significantly less key values (num_rows) in a bitmap index than in the table it points to.\n\n---\n### Query 6\n###### *Shortcut:* \u003cins\u003e[To the top](#Table-of-Contents)\u003c/ins\u003e\n\n**Select the programs (curso) that have classes with all the existing types.**\n#### SQL Formulation\n```sql\nSELECT DISTINCT UCS.curso AS programm\nFROM XUCS UCS JOIN XTIPOSAULA CLASS_TYPES ON UCS.codigo = CLASS_TYPES.codigo\nGROUP BY UCS.curso\nHAVING COUNT(DISTINCT CLASS_TYPES.tipo) = (\n    SELECT COUNT(DISTINCT tipo)\n    FROM XTIPOSAULA\n)     \n```\n\n#### Result (in JSON format)\n```json\n{\n  \"results\" : [\n    {\n      \"columns\" : [\n        {\n          \"name\" : \"PROGRAMM\",\n          \"type\" : \"NUMBER\"\n        }\n      ],\n      \"items\" : [\n        {\n          \"programm\" : 9461\n        },\n        {\n          \"programm\" : 4495\n        },\n        {\n          \"programm\" : 9508\n        },\n        {\n          \"programm\" : 2021\n        }\n      ]\n    }\n  ]\n}\n```\n#### Execution Plan\n|           | Environment X | Environment Y | Environment Z |\n| --------- | ------------- | ------------- | ------------- |\n| Cost      |       51      |      51       |       45      |\n\n##### Environment X\n![](https://i.imgur.com/DVNERWm.png)\n\n##### Environment Y\nIn this query we can see that using primary and foreign keys didn't change the cost of the query, since the optimizer decided to do a full access to all tables, instead of a fast full access.\n\n![](https://i.imgur.com/jM7Vfo0.png)\n\n##### Environment Z\nThis are the indexes used to improve the cost of the query. It was also used the constraints defined from the previous environment. \n```sql\nCREATE INDEX IX_ZTIPOSAULA_TIPO ON ZTIPOSAULA (tipo);\nCREATE INDEX IX_ZUCS_CODIGO_CURSO ON ZUCS(codigo, curso);\n```\nThe first one is useful since the **tipo** column from **ZTIPOSAULA** is used in the **HAVING** clause to determine if a course has all types of classes. \nThis makes the **HAVING** statement have a cost of 13 instead of 37. In spite of this, the total cost of the query won't change with this index.\n\nThe second one is more useful because it reduces the cost of the **hash join** between **ZUCS** and **ZTIPOSAULA**. It uses a composite index with the columns **codigo** and **curso**.\n\n\n![](https://i.imgur.com/zIr0tTW.png)\n\n\n---\n\n# Conclusion\n###### *Shortcut:* \u003cins\u003e[To the top](#Table-of-Contents)\u003c/ins\u003e\n\nWe learned that the first thing to do when trying to optimize queries is to add the primary and foreign keys constraints since most queries this is where the cost was substantially lower. We also learned about query optimization, where different formulations can lead to very distinct results, such as doing unnecessary joins, complex operations, etc.\n\nMoreover, the B-tree indexes reduced even further the cost of most queries. Our motto for adding them was to first add on columns used in joins. These columns most commonly refer to foreign keys, where, in some environments, such as Oracle SQL Developer, this is not done automatically. Additionally, we also added indexes to columns used in **WHERE** conditions. \n\nApart from single-column indexes, we also used composite indexes in more than one query to reduce the overall number of indexes (and their size).\n\nAlthough we explored Bitmap indexes, they were not used since there isn't any column that needs an index while having low cardinality, i.e., where columns have lots of duplicate values.\n\nFinally, we also tried to experiment with **MATERIALIZED VIEWS** (*reference to [Query 3.1](#Query-3.1)*) that gave us better results but wasn't explored in too much detail due to time constraints.\n\nIn conclusion, we learned a lot about query optimization in SQL and indexes during this project. In future work, we can further improve the results and keep learning, as this process could take some time before reaching an optimal solution for all queries.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmotapinto%2Fsql-query-optimization","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmotapinto%2Fsql-query-optimization","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmotapinto%2Fsql-query-optimization/lists"}