optimizing queries using ctes and window functions
play

Optimizing Queries Using CTEs and Window Functions Viceniu Ciorbaru - PowerPoint PPT Presentation

Optimizing Queries Using CTEs and Window Functions Viceniu Ciorbaru Software Engineer @ MariaDB Foundation Agenda What are Common Table Expressions (CTEs)? What are Window Functions? Practical use cases Why are window


  1. Optimizing Queries Using CTEs and Window Functions Vicențiu Ciorbaru Software Engineer @ MariaDB Foundation

  2. Agenda ■ What are Common Table Expressions (CTEs)? ■ What are Window Functions? ■ Practical use cases ■ Why are window functions fast? ■ Development status in MariaDB

  3. What are CTEs? Syntax WITH engineers AS ( SELECT * FROM employees WHERE dept=”Engineering” ) SELECT * FROM engineers WHERE ...

  4. What are CTEs? Syntax WITH engineers AS ( Keyword SELECT * FROM employees WHERE dept=”Engineering” ) SELECT * FROM engineers WHERE ...

  5. What are CTEs? Syntax WITH engineers AS ( CTE Name SELECT * FROM employees WHERE dept=”Engineering” ) SELECT * FROM engineers WHERE ...

  6. What are CTEs? Syntax WITH engineers AS ( SELECT * FROM employees CTE Body WHERE dept=”Engineering” ) SELECT * FROM engineers WHERE ...

  7. What are CTEs? Syntax WITH engineers AS ( SELECT * FROM employees WHERE dept=”Engineering” ) SELECT * FROM engineers CTE Usage WHERE ...

  8. What are CTEs? CTEs are similar to derived tables. WITH engineers AS ( SELECT * SELECT * FROM (SELECT * FROM employees FROM employees WHERE dept=”Engineering” WHERE dept=”Engineering”) AS engineers ) WHERE ... SELECT * FROM engineers WHERE ...

  9. What are CTEs? CTEs are more readable than derived tables. WITH engineers AS ( SELECT * SELECT * FROM (SELECT * FROM employees FROM (SELECT * WHERE dept=”Engineering” FROM employees ), WHERE dept=”Engineering”) AS engineers eu_engineers AS ( WHERE country IN (”NL”,...)) SELECT * WHERE ... FROM engineers WHERE country IN (”NL”,...) ) SELECT * FROM eu_engineers WHERE ...

  10. What are CTEs? CTEs are more readable than derived tables. WITH engineers AS ( SELECT * SELECT * FROM (SELECT * FROM employees FROM (SELECT * WHERE dept=”Engineering” FROM employees ), WHERE dept=”Engineering”) AS engineers eu_engineers AS ( WHERE country IN (”NL”,...)) SELECT * WHERE ... FROM engineers WHERE country IN (”NL”,...) ) SELECT * FROM eu_engineers WHERE ... Linear View Nested View

  11. What are CTEs? Example: Year-over-year comparisons WITH sales_product_year AS ( SELECT * SELECT FROM product, sales_product_year CUR, year(ship_date) as year, sales_product_year PREV, SUM(price) as total_amt WHERE FROM CUR.product = PREV.product AND item_sales CUR.year = PREV.year + 1 AND GROUP BY CUR.total_amt > PREV.total_amt product, year )

  12. Summary on CTEs ■ Identified by the WITH clause. ■ Similar to derived tables in the FROM clause. ■ More expressive and provide cleaner code. ■ Can produce more efficient query plans.

  13. CTE execution Basic algorithm ● Materialize each CTE occurrence into WITH sales_product_year AS ( SELECT a Temporary Table product, year(ship_date) as year, SUM(price) as total_amt ● Often Not optimal! FROM item_sales GROUP BY product, year ) SELECT * FROM sales_product_year CUR, sales_product_year PREV, WHERE CUR.product = PREV.product AND CUR.year = PREV.year + 1 AND CUR.total_amt > PREV.total_amt

  14. CTE optimization #1 CTE reuse ● Materialize each CTE occurrence into WITH sales_product_year AS ( SELECT a Temporary Table product, year(ship_date) as year, SUM(price) as total_amt FROM item_sales GROUP BY product, year ) SELECT * FROM sales_product_year CUR, We can reuse CTE here! sales_product_year PREV, WHERE CUR.product = PREV.product AND CUR.year = PREV.year + 1 AND CUR.total_amt > PREV.total_amt

  15. CTE optimization #1 CTE reuse ● Materialize each distinct CTE WITH sales_product_year AS ( SELECT occurrence into a Temporary Table product, year(ship_date) as year, SUM(price) as total_amt FROM item_sales GROUP BY product, year ) SELECT * FROM sales_product_year CUR, Materialize only once! sales_product_year PREV, WHERE CUR.product = PREV.product AND CUR.year = PREV.year + 1 AND CUR.total_amt > PREV.total_amt

  16. CTE optimization #1 CTE reuse ● Materialize each distinct CTE WITH sales_product_year AS ( SELECT occurrence into a Temporary Table product, ● Not compatible with other year(ship_date) as year, SUM(price) as total_amt optimizations. FROM item_sales GROUP BY product, year ) SELECT * FROM sales_product_year CUR, Materialize only once! sales_product_year PREV, WHERE CUR.product = PREV.product AND CUR.year = PREV.year + 1 AND CUR.total_amt > PREV.total_amt

  17. CTE optimization #2 CTE merging WITH engineers AS ( SELECT * FROM EMPLOYEES WHERE dept='Development' ) SELECT ... FROM engineers E, support_cases SC WHERE E.name=SC.assignee and SC.created='2017-04-10' and E.location='New York' Requirements: ● CTE is used in a JOIN, no GROUP BY, DISTINCT, etc.

  18. CTE optimization #2 CTE merging WITH engineers AS ( SELECT SELECT * FROM EMPLOYEES ... WHERE FROM dept='Development' employees E, ) support_cases SC SELECT WHERE ... E.name=SC.assignee and FROM SC.created='2017-04-10' and engineers E, E.location='New York' support_cases SC E.dept='Development' WHERE E.name=SC.assignee and SC.created='2017-04-10' and E.location='New York' Requirements: ● CTE is used in a JOIN, no GROUP BY, DISTINCT, etc.

  19. CTE optimization #2 CTE merging WITH engineers AS ( SELECT SELECT * FROM EMPLOYEES ... WHERE FROM dept='Development' employees E, ) support_cases SC SELECT WHERE ... E.name=SC.assignee and FROM SC.created='2017-04-10' and engineers E, E.location='New York' support_cases SC E.dept='Development' WHERE E.name=SC.assignee and SC.created='2017-04-10' and ● CTE merged into parent join. E.location='New York' ● Now optimizer can pick any query plan. Requirements: ● Same algorithm is used for VIEWS ● CTE is used in a JOIN, no GROUP (ALGORITHM = MERGE) BY, DISTINCT, etc.

  20. CTE optimization #3 Condition pushdown WITH sales_per_year AS ( SELECT year(order.date) AS year sum(order.amount) AS sales FROM order GROUP BY year ) SELECT * FROM sales_per_year WHERE year in ('2015','2016')

  21. CTE optimization #3 Condition pushdown WITH sales_per_year AS ( SELECT year(order.date) AS year sum(order.amount) AS sales FROM order GROUP BY year ) SELECT * FROM sales_per_year WHERE year in ('2015','2016') Requirements: ● Merging is not possible (GROUP BY exists) ● Conditions in outer select

  22. CTE optimization #3 Condition pushdown WITH sales_per_year AS ( WITH sales_per_year AS ( SELECT SELECT year(order.date) AS year year(order.date) as year sum(order.amount) AS sales sum(order.amount) as sales FROM FROM order order GROUP BY WHERE year year in ('2015','2016') ) GROUP BY SELECT * year FROM sales_per_year ) WHERE SELECT * year in ('2015','2016') FROM sales_per_year Requirements: ● Merging is not possible (GROUP BY exists) ● Conditions in outer select

  23. CTE optimization #3 Condition pushdown ● Makes temporary tables smaller. WITH sales_per_year AS ( SELECT ● Can filter out whole groups. year(order.date) as year sum(order.amount) as sales ● Works for derived tables and views. FROM order WHERE year in ('2015','2016') ● Implemented as a GSoC project: GROUP BY year ) SELECT * “Pushing conditions into non-mergeable FROM sales_per_year views and derived tables in MariaDB”

  24. CTE Optimizations Summary CTE Merge Condition CTE reuse pushdown MariaDB 10.2 ✔ ✔ ✘ MS SQL Server ✔ ✔ ✘ PostgreSQL ✘ ✘ ✔ MySQL ✔ * ✔ ✘ 8.0.0-labs-optimizer ● Merge and condition pushdown are most important ○ Can not be used at the same time as CTE reuse ● PostgreSQL considers CTEs optimization barriers ● MySQL (8.0) tries merging, otherwise reuse

  25. What are window functions? ■ Similar to aggregate functions ○ Computed over a sequence of rows ■ But they provide one result per row ○ Like regular functions! ■ Identified by the OVER clause.

  26. What are window functions? Let’s start with a “function like” example SELECT email, first_name, last_name, account_type FROM users ORDER BY email; +------------------------+------------+-----------+--------------+ | email | first_name | last_name | account_type | +------------------------+------------+-----------+--------------+ | admin@boss.org | Admin | Boss | admin | | bob.carlsen@foo.bar | Bob | Carlsen | regular | | eddie.stevens@data.org | Eddie | Stevens | regular | | john.smith@xyz.org | John | Smith | regular | | root@boss.org | Root | Chief | admin | +------------------------+------------+-----------+--------------+

Recommend


More recommend