How a database optimizer gets your data, fast Viceniu Ciorbaru - - PowerPoint PPT Presentation

how a database optimizer gets your data fast
SMART_READER_LITE
LIVE PREVIEW

How a database optimizer gets your data, fast Viceniu Ciorbaru - - PowerPoint PPT Presentation

How a database optimizer gets your data, fast Viceniu Ciorbaru Software Developer Team Lead @ MariaDB Foundation Percona Live Europe 2019 30 Sept - 2 Oct Amsterdam, Netherlands whoami Viceniu Ciorbaru MariaDB Foundation,


slide-1
SLIDE 1

How a database

  • ptimizer gets your data,

fast

Vicențiu Ciorbaru Software Developer Team Lead @ MariaDB Foundation

Percona Live Europe 2019 30 Sept - 2 Oct Amsterdam, Netherlands

slide-2
SLIDE 2

2

whoami

  • Vicențiu Ciorbaru
  • MariaDB Foundation,

Software Developer Team Lead

  • MariaDB developer since 2013-…
  • Implemented Roles, Window Functions and others

MariaDB Foundation https://mariadb.org

slide-3
SLIDE 3

3

Goal of a query optimizer

  • Produce a query plan that executes your query in the fastest time possible.
  • Optimizer has many tools at its disposal:

○ It can choose to pre-read tables ○ Cache results (such as uncorrelated subqueries) ○ Use indexes to look up values ○ Use indexes to access data in-order and avoid sorting ○ Rewrite a query (more on this later) ○ And more...

  • Number of possible plans grows exponentially with # tables

MariaDB Foundation https://mariadb.org

slide-4
SLIDE 4

4

Goal of a query optimizer

  • Not enough time to try out every possible plan
  • In a "perfect world" any query should be performing as fast as possible.
  • Many queries do!
  • But sometimes…

MariaDB Foundation https://mariadb.org

slide-5
SLIDE 5

Statistics based

  • ptimizations

5 MariaDB Foundation https://mariadb.org

slide-6
SLIDE 6

6

What optimizer can ask the engine

  • “how many rows does the table havе?”
  • “what would it cost to scan the whole table?”
  • “what would it cost to read that many rows from this index?”
  • “how many distinct key values are in this index?”
  • “how many keys lie in that range of values in this index?”

MariaDB Foundation https://mariadb.org

slide-7
SLIDE 7

7

A problem: instability

  • DBT-3 Q8: National Market Share Query — 8 InnoDB tables

○ 4 different plans ○ from 7 minutes to 1.2 hours

  • DBT-3 Q7: Volume Shipping Query — 6 InnoDB tables

○ 7 different plans ○ from 12 minutes to many hours (and timeout)

MariaDB Foundation https://mariadb.org

slide-8
SLIDE 8

8

A problem: instability

  • DBT-3 Q8: National Market Share Query — 8 InnoDB tables

○ 4 different plans ○ from 7 minutes to 1.2 hours

  • DBT-3 Q7: Volume Shipping Query — 6 InnoDB tables

○ 7 different plans ○ from 12 minutes to many hours (and timeout)

  • What about InnoDB persistent statistics?

MariaDB Foundation https://mariadb.org

slide-9
SLIDE 9

9

A problem: All engines are liars

MariaDB> CREATE TABLE t1 (a INT, b INT, c INT, KEY(a,b)) ENGINE=MyISAM; MariaDB> INSERT t1 VALUES (RAND()*100000,RAND()*100000,RAND()*100000); MariaDB> ... 400 000 rows … MariaDB> SELECT COUNT(DISTINCT a) AS cardinality FROM t1; +-------------+ | cardinality | +-------------+ | 97794 | +-------------+

MariaDB Foundation https://mariadb.org

slide-10
SLIDE 10

10

A problem: All engines are liars

MariaDB> SELECT cardinality FROM information_schema.statistics

  • -> WHERE table_name='t1' AND column_name='a';

+-------------+ | cardinality | +-------------+ | 98304 | +-------------+ MariaDB> ALTER TABLE t1 ENGINE=InnoDB; MariaDB> SELECT cardinality FROM information_schema.statistics

  • -> WHERE table_name='t1' AND column_name='a';

+-------------+ | cardinality | +-------------+ | 196914 | +-------------+

MariaDB Foundation https://mariadb.org

slide-11
SLIDE 11

11

A problem: An index is required

  • Takes storage space
  • Needs to be updated for every INSERT / UPDATE / DELETE
  • More indexes make INSERT / UPDATE / DELETE slow

MariaDB Foundation https://mariadb.org

slide-12
SLIDE 12

12

A problem: An index is required

  • Takes storage space
  • Needs to be updated for every INSERT / UPDATE / DELETE
  • More indexes make INSERT / UPDATE / DELETE slow
  • Too expensive if you only need statistics!

MariaDB Foundation https://mariadb.org

slide-13
SLIDE 13

13

Solution: Engine Independent Table Statistics

  • Stable - Solves Instability
  • Precise - Solves Storage Engine lying
  • Detailed - Stores more information that most storage engines
  • Identical for all engines
  • Comparable - Format is "humanly readable"

MariaDB Foundation https://mariadb.org

slide-14
SLIDE 14

14

How does it work?

  • new tables in the mysql schema
  • @@use_stat_tables = [ never | complementary | preferably ]
  • @@optimizer_use_condition_selectivity = 1 ... 5
  • ANALYZE TABLE ... [ PERSISTENT FOR ... ]

MariaDB Foundation https://mariadb.org

slide-15
SLIDE 15

15

An example is worth a thousand words...

  • https://dev.mysql.com/doc/employee/en/
  • https://github.com/datacharmer/test_db
  • 300,000 employees, 2.8 millions salary payments, 167 MB of data

MariaDB> source employees.sql MariaDB> SET USE_STAT_TABLES=PREFERABLY; Query OK, 0 rows affected (0.00 sec) MariaDB> ANALYZE TABLE departments, dept_emp, dept_manager,

  • > employees, salaries, titles;

12 rows in set (18.49 sec)

MariaDB Foundation https://mariadb.org

slide-16
SLIDE 16

16

Example: per-column statistics

MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=1; Query OK, 0 rows affected (0.01 sec) MariaDB> SELECT * FROM departments JOIN dept_emp USING (dept_no)

  • > JOIN employees USING (emp_no)
  • > JOIN titles USING (emp_no)
  • > WHERE title='Manager';

24 rows in set (15.13 sec)

MariaDB Foundation https://mariadb.org

slide-17
SLIDE 17

17

Example: per-column statistics

MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=1; Query OK, 0 rows affected (0.01 sec) MariaDB> SELECT * FROM departments JOIN dept_emp USING (dept_no)

  • > JOIN employees USING (emp_no)
  • > JOIN titles USING (emp_no)
  • > WHERE title='Manager';

24 rows in set (15.13 sec) MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=3; Query OK, 0 rows affected (0.01 sec) MariaDB> SELECT * FROM departments JOIN dept_emp USING (dept_no)

  • > JOIN employees USING (emp_no)
  • > JOIN titles USING (emp_no)
  • > WHERE title='Manager';

24 rows in set (0.53 sec)

MariaDB Foundation https://mariadb.org

slide-18
SLIDE 18

18

Example: per-column statistics

+-------------+--------+---------+-------+----------+-----------------------+ | table | type | key | rows | filtered | Extra | +-------------+--------+---------+-------+----------+-----------------------+ | departments | ALL | NULL | 9 | 100.00 | | | dept_emp | ref | dept_no | 36844 | 100.00 | | | employees | eq_ref | PRIMARY | 1 | 100.00 | | | titles | ref | PRIMARY | 1 | 100.00 | Using index condition | +-------------+--------+---------+-------+----------+-----------------------+ MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=3; +-------------+--------+---------+--------+----------+----------------------.. | table | type | key | rows | filtered | Extra +-------------+--------+---------+--------+----------+----------------------.. | titles | ALL | NULL | 443308 | 14.29 | Using where | employees | eq_ref | PRIMARY | 1 | 100.00 | | dept_emp | ref | PRIMARY | 1 | 100.00 | | departments | ALL | NULL | 9 | 77.78 | Using where; Using join +-------------+--------+---------+--------+----------+----------------------..

MariaDB Foundation https://mariadb.org

slide-19
SLIDE 19

19

Example: per-column statistics

+-------------+--------+---------+-------+----------+-----------------------+ | table | type | key | rows | filtered | Extra | +-------------+--------+---------+-------+----------+-----------------------+ | departments | ALL | NULL | 9 | 100.00 | | | dept_emp | ref | dept_no | 36844 | 100.00 | | | employees | eq_ref | PRIMARY | 1 | 100.00 | | | titles | ref | PRIMARY | 1 | 100.00 | Using index condition | +-------------+--------+---------+-------+----------+-----------------------+ MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=3; +-------------+--------+---------+--------+----------+----------------------.. | table | type | key | rows | filtered | Extra +-------------+--------+---------+--------+----------+----------------------.. | titles | ALL | NULL | 443308 | 14.29 | Using where | employees | eq_ref | PRIMARY | 1 | 100.00 | | dept_emp | ref | PRIMARY | 1 | 100.00 | | departments | ALL | NULL | 9 | 77.78 | Using where; Using join +-------------+--------+---------+--------+----------+----------------------..

MariaDB Foundation https://mariadb.org

slide-20
SLIDE 20

20

Example: per-column statistics

+-------------+--------+---------+-------+----------+-----------------------+ | table | type | key | rows | filtered | Extra | +-------------+--------+---------+-------+----------+-----------------------+ | departments | ALL | NULL | 9 | 100.00 | | | dept_emp | ref | dept_no | 36844 | 100.00 | | | employees | eq_ref | PRIMARY | 1 | 100.00 | | | titles | ref | PRIMARY | 1 | 100.00 | Using index condition | +-------------+--------+---------+-------+----------+-----------------------+ MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=3; +-------------+--------+---------+--------+----------+----------------------.. | table | type | key | rows | filtered | Extra +-------------+--------+---------+--------+----------+----------------------.. | titles | ALL | NULL | 443308 | 14.29 | Using where | employees | eq_ref | PRIMARY | 1 | 100.00 | | dept_emp | ref | PRIMARY | 1 | 100.00 | | departments | ALL | NULL | 9 | 77.78 | Using where; Using join +-------------+--------+---------+--------+----------+----------------------..

MariaDB Foundation https://mariadb.org

slide-21
SLIDE 21

21

Equi-height Histograms

MariaDB Foundation https://mariadb.org

slide-22
SLIDE 22

22

Equi-height Histograms

MariaDB Foundation https://mariadb.org

slide-23
SLIDE 23

23

Example: non-uniform distribution

MariaDB> SELECT (MIN(salary)+MAX(salary))/2 FROM salaries; +-----------------------------+ | 98421.5000 | +-----------------------------+ MariaDB> SELECT * FROM employees JOIN salaries USING (emp_no)

  • > JOIN titles USING (emp_no)
  • > WHERE salary > 100000;

166014 rows in set (18.79 sec) MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=4; Query OK, 0 rows affected (0.00 sec) MariaDB> SELECT * FROM employees JOIN salaries USING (emp_no)

  • > JOIN titles USING (emp_no)
  • > WHERE salary > 100000;

166014 rows in set (6.64 sec)

MariaDB Foundation https://mariadb.org

slide-24
SLIDE 24

24

Example: per-column statistics

MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=3; +------+-----------+--------+---------+--------+----------+-------------+ | id | table | type | key | rows | filtered | Extra | +------+-----------+--------+---------+--------+----------+-------------+ | 1 | titles | ALL | NULL | 443308 | 100.00 | | | 1 | employees | eq_ref | PRIMARY | 1 | 100.00 | | | 1 | salaries | ref | PRIMARY | 9 | 48.68 | Using where | +------+-----------+--------+---------+--------+----------+-------------+ MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=4; +------+-----------+--------+---------+---------+----------+-------------+ | id | table | type | key | rows | filtered | Extra | +------+-----------+--------+---------+---------+----------+-------------+ | 1 | salaries | ALL | NULL | 2844047 | 4.76 | Using where | | 1 | employees | eq_ref | PRIMARY | 1 | 100.00 | | | 1 | titles | ref | PRIMARY | 1 | 100.00 | | +------+-----------+--------+---------+---------+----------+-------------+

MariaDB Foundation https://mariadb.org

slide-25
SLIDE 25

25

Example: per-column statistics

MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=3; +------+-----------+--------+---------+--------+----------+-------------+ | id | table | type | key | rows | filtered | Extra | +------+-----------+--------+---------+--------+----------+-------------+ | 1 | titles | ALL | NULL | 443308 | 100.00 | | | 1 | employees | eq_ref | PRIMARY | 1 | 100.00 | | | 1 | salaries | ref | PRIMARY | 9 | 48.68 | Using where | +------+-----------+--------+---------+--------+----------+-------------+ MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=4; +------+-----------+--------+---------+---------+----------+-------------+ | id | table | type | key | rows | filtered | Extra | +------+-----------+--------+---------+---------+----------+-------------+ | 1 | salaries | ALL | NULL | 2844047 | 4.76 | Using where | | 1 | employees | eq_ref | PRIMARY | 1 | 100.00 | | | 1 | titles | ref | PRIMARY | 1 | 100.00 | | +------+-----------+--------+---------+---------+----------+-------------+

MariaDB Foundation https://mariadb.org

slide-26
SLIDE 26

26

Example: per-column statistics

MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=3; +------+-----------+--------+---------+--------+----------+-------------+ | id | table | type | key | rows | filtered | Extra | +------+-----------+--------+---------+--------+----------+-------------+ | 1 | titles | ALL | NULL | 443308 | 100.00 | | | 1 | employees | eq_ref | PRIMARY | 1 | 100.00 | | | 1 | salaries | ref | PRIMARY | 9 | 48.68 | Using where | +------+-----------+--------+---------+--------+----------+-------------+ MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=4; +------+-----------+--------+---------+---------+----------+-------------+ | id | table | type | key | rows | filtered | Extra | +------+-----------+--------+---------+---------+----------+-------------+ | 1 | salaries | ALL | NULL | 2844047 | 4.76 | Using where | | 1 | employees | eq_ref | PRIMARY | 1 | 100.00 | | | 1 | titles | ref | PRIMARY | 1 | 100.00 | | +------+-----------+--------+---------+---------+----------+-------------+

MariaDB Foundation https://mariadb.org

slide-27
SLIDE 27

27

Example: sampling

MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=4; MariaDB> SELECT dept_name, AVG(salary)

  • -> FROM departments JOIN dept_emp USING (dept_no)
  • -> JOIN employees USING (emp_no)
  • -> JOIN salaries USING (emp_no)
  • -> WHERE last_name LIKE '%off' GROUP BY dept_name;

9 rows in set (5.06 sec) MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=5; MariaDB> SELECT dept_name, AVG(salary)

  • -> FROM departments JOIN dept_emp USING (dept_no)
  • -> JOIN employees USING (emp_no)
  • -> JOIN salaries USING (emp_no)
  • -> WHERE last_name LIKE '%off' GROUP BY dept_name;

9 rows in set (0.40 sec)

MariaDB Foundation https://mariadb.org

slide-28
SLIDE 28

28

Example: per-column statistics

+-------------+--------+---------+-------+----------+---------------------+ | table | type | key | rows | filtered | Extra | +-------------+--------+---------+-------+----------+---------------------+ | departments | ALL | NULL | 9 | 100.00 | temporary; filesort | | dept_emp | ref | dept_no | 36844 | 100.00 | | | employees | eq_ref | PRIMARY | 1 | 100.00 | where | | salaries | ref | PRIMARY | 9 | 100.00 | | +-------------+--------+---------+-------+----------+---------------------+ MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=5; +-------------+-------+---------+--------+----------+--------------------... | table | type | key | rows | filtered | Extra ... +-------------+-------+---------+--------+----------+--------------------... | employees | ALL | NULL | 300024 | 1.00 | where; temporary; filesort | dept_emp | ref | PRIMARY | 1 | 100.00 | index | departments | ALL | NULL | 9 | 77.78 | where; join buffer (flat, | salaries | ref | PRIMARY | 9 | 100.00 | +-------------+-------+---------+--------+----------+--------------------...

MariaDB Foundation https://mariadb.org

slide-29
SLIDE 29

29

Example: per-column statistics

+-------------+--------+---------+-------+----------+---------------------+ | table | type | key | rows | filtered | Extra | +-------------+--------+---------+-------+----------+---------------------+ | departments | ALL | NULL | 9 | 100.00 | temporary; filesort | | dept_emp | ref | dept_no | 36844 | 100.00 | | | employees | eq_ref | PRIMARY | 1 | 100.00 | where | | salaries | ref | PRIMARY | 9 | 100.00 | | +-------------+--------+---------+-------+----------+---------------------+ MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=5; +-------------+-------+---------+--------+----------+--------------------... | table | type | key | rows | filtered | Extra ... +-------------+-------+---------+--------+----------+--------------------... | employees | ALL | NULL | 300024 | 1.00 | where; temporary; filesort | dept_emp | ref | PRIMARY | 1 | 100.00 | index | departments | ALL | NULL | 9 | 77.78 | where; join buffer (flat, | salaries | ref | PRIMARY | 9 | 100.00 | +-------------+-------+---------+--------+----------+--------------------...

MariaDB Foundation https://mariadb.org

slide-30
SLIDE 30

30

Example: per-column statistics

+-------------+--------+---------+-------+----------+---------------------+ | table | type | key | rows | filtered | Extra | +-------------+--------+---------+-------+----------+---------------------+ | departments | ALL | NULL | 9 | 100.00 | temporary; filesort | | dept_emp | ref | dept_no | 36844 | 100.00 | | | employees | eq_ref | PRIMARY | 1 | 100.00 | where | | salaries | ref | PRIMARY | 9 | 100.00 | | +-------------+--------+---------+-------+----------+---------------------+ MariaDB> SET OPTIMIZER_USE_CONDITION_SELECTIVITY=5; +-------------+-------+---------+--------+----------+--------------------... | table | type | key | rows | filtered | Extra ... +-------------+-------+---------+--------+----------+--------------------... | employees | ALL | NULL | 300024 | 1.00 | where; temporary; filesort | dept_emp | ref | PRIMARY | 1 | 100.00 | index | departments | ALL | NULL | 9 | 77.78 | where; join buffer (flat, | salaries | ref | PRIMARY | 9 | 100.00 | +-------------+-------+---------+--------+----------+--------------------...

MariaDB Foundation https://mariadb.org

slide-31
SLIDE 31

31

MariaDB 10.0 (GA 2014)

  • Per table: number of rows
  • Per index: number of distinct values
  • Per column:

○ number of distinct values ○ min and max values, amount of NULLs, average value length

  • Equi-height histogram
  • Sampling for LIKE predicates

MariaDB Foundation https://mariadb.org

slide-32
SLIDE 32

32

MySQL 8.0 (GA 2018)

  • Optimizer Statistics
  • Per column:

○ Amount of NULLs ○ Equi-height and “singleton” histograms ○ Faster than MariaDB 10.0 on large tables ○ Skips values to keep the data set small

MariaDB Foundation https://mariadb.org

slide-33
SLIDE 33

33

MariaDB 10.4 (GA 2019)

  • Statistics Tables are Enabled by default
  • Can collect histograms through sampling

○ Uses Bernoulli Sampling ○ Server variable analyze_sample_percentage ○ Set to 0 to let MariaDB decide how many rows to sample.

  • Uses the unsmoothed first-order jackknife estimator to estimate total

cardinality.

  • At least as fast as MySQL 8.0 for large tables

MariaDB Foundation https://mariadb.org

slide-34
SLIDE 34

Query rewriting

34 MariaDB Foundation https://mariadb.org

slide-35
SLIDE 35

35

Background on optimizations

  • A derived table is a table in the FROM clause, defined as a subquery.

SELECT * FROM (SELECT a FROM t1) der_t1;

MariaDB Foundation https://mariadb.org

slide-36
SLIDE 36

36

VIP Customers and their orders

select * from vip_customers, (select * from orders where order_date between '2017-10-01' and '2017-10-31') as OCT_ORDERS where OCT_ORDERS.amount > 1000000 and OCT_ORDERS.customer_id = vip_customers.customer_id;

MariaDB Foundation https://mariadb.org

slide-37
SLIDE 37

37

Naive execution

select * from vip_customers, (select * from orders where order_datebetween '2017-10-01' and '2017-10-31') as OCT_ORDERS where OCT_ORDERS.amount > 1000000 and OCT_ORDERS.customer_id = vip_customers.customer_id;

  • rders

OCT_ORDERS

DATE FILTER amount > 1000000 JOIN

vip_customers RESULT

MariaDB Foundation https://mariadb.org

slide-38
SLIDE 38

38

Derived Table Merge

select * from vip_customers vc, (select * from orders where

  • rder_date between

'2017-10-01' and '2017-10-31' ) as OCT_ORDERS where OCT_ORDERS.amount > 1M and OCT_ORDERS.customer_id = vc.customer_id; select * from vip_customers vc,

  • rders o

where

  • .amount > 1M and
  • .customer_id = vc.customer_id

and

  • .order_date between

'2017-10-01' and '2017-10-31';

MariaDB Foundation https://mariadb.org

slide-39
SLIDE 39

39

Explain shows table is merged

explain select * from vip_customers, (select * from orders where order_date between '2017-10-01' and '2017-10-31') as OCT_ORDERS where OCT_ORDERS.amount > 1000000 and OCT_ORDERS.customer_id = vip_customers.customer_id; +----+-------------+---------------+------+..+---------+-------------+ |id | select_type | table | type |..| rows | Extra | +----+-------------+---------------+------+..+---------+-------------+ | 1 | SIMPLE | vip_customers | ALL |..| 101 | | | 1 | SIMPLE | orders | ALL |..| 1000000 | Using where;| +----+-------------+---------------+------+..+---------+-------------+

MariaDB Foundation https://mariadb.org

slide-40
SLIDE 40

40

Execution after merge

  • rders

OCT_ORDERS

amount > 1M JOIN

vip_customers RESUL T

select * from vip_customers vc,

  • rders o

where

  • .amount > 1M and
  • .customer_id = vc.customer_id and
  • .order_date between '2017-10-01' and '2017-10-31';

MariaDB Foundation https://mariadb.org

slide-41
SLIDE 41

41

Execution after merge

  • rders

OCT_ORDERS

amount > 1M JOIN

vip_customers RESUL T

select * from vip_customers vc,

  • rders o

where

  • .amount > 1M and
  • .customer_id = vc.customer_id and
  • .order_date between '2017-10-01' and '2017-10-31';

Merging is good! It simplifies the query!

MariaDB Foundation https://mariadb.org

slide-42
SLIDE 42

42

Execution after merge

  • rders

OCT_ORDERS

amount > 1M JOIN

vip_customers RESUL T

select * from vip_customers vc,

  • rders o

where

  • .amount > 1M and
  • .customer_id = vc.customer_id and
  • .order_date between '2017-10-01' and '2017-10-31';

Merging is good! It simplifies the query! Works in all stable MariaDB & MySQL versions.

MariaDB Foundation https://mariadb.org

slide-43
SLIDE 43

43

Execution after merge

  • rders

OCT_ORDERS

amount > 1M JOIN

vip_customers RESUL T

select * from vip_customers vc,

  • rders o

where

  • .amount > 1M and
  • .customer_id = vc.customer_id and
  • .order_date between '2017-10-01' and '2017-10-31';

Merging is good! It simplifies the query! Works in all stable MariaDB & MySQL versions. Can not be used when aggregation is present. :(

MariaDB Foundation https://mariadb.org

slide-44
SLIDE 44

create view OCT_TOTALS as select customer_id, SUM(amount) as TOTAL_AMT from orders where order_date between '2017-10-01' and '2017-10-31' group by customer_id select * from OCT_TOTALS where customer_id=1

Condition pushdown

44 MariaDB Foundation https://mariadb.org

slide-45
SLIDE 45

create view OCT_TOTALS as select customer_id, SUM(amount) as TOTAL_AMT from orders where order_date between '2017-10-01' and '2017-10-31' group by customer_id select * from OCT_TOTALS where customer_id=1

Condition pushdown

45

There are a lot of customers and we only want the data for 1.

MariaDB Foundation https://mariadb.org

slide-46
SLIDE 46

create view OCT_TOTALS as select customer_id, SUM(amount) as TOTAL_AMT from orders where order_date between '2017-10-01' and '2017-10-31' group by customer_id select * from OCT_TOTALS where customer_id=1

Condition pushdown

46

We can push the condition to the where clause!

MariaDB Foundation https://mariadb.org

slide-47
SLIDE 47

create view OCT_TOTALS as select customer_id, SUM(amount) as TOTAL_AMT from orders where order_date between '2017-10-01' and '2017-10-31' group by customer_id select * from OCT_TOTALS where customer_id=1

Condition pushdown

47

This tactic works for Window Functions too!

MariaDB Foundation https://mariadb.org

slide-48
SLIDE 48

create view top_three_orders as select * from ( select customer_id, amount, rank() over (partition by customer_id

  • rder by amount desc) as order_rank from orders) as

ranked_orders where order_rank < 3

+-------------+--------+------------+ | customer_id | amount | order_rank | +-------------+--------+------------+ | 1 | 10000 | 1 | | 1 | 9500 | 2 | | 1 | 400 | 3 | | 2 | 3200 | 1 | | 2 | 1000 | 2 | .....................................

select * from top_three_orders where customer_id = 1

Condition pushdown through PARTITION BY

48 MariaDB Foundation https://mariadb.org

slide-49
SLIDE 49

create view top_three_orders as select * from ( select customer_id, amount, rank() over (partition by customer_id

  • rder by amount desc) as order_rank from orders) as

ranked_orders where order_rank < 3

+-------------+--------+------------+ | customer_id | amount | order_rank | +-------------+--------+------------+ | 1 | 10000 | 1 | | 1 | 9500 | 2 | | 1 | 400 | 3 | | 2 | 3200 | 1 | | 2 | 1000 | 2 | .....................................

select * from top_three_orders where customer_id = 1

Condition pushdown through PARTITION BY

49 MariaDB Foundation https://mariadb.org

slide-50
SLIDE 50

MariaDB 10.2, MySQL 8.0 ■ Compute top_three_orders for all customers ■ Select rows with customer_id = 1 MariaDB 10.3 and onwards (and e.g. PostgreSQL) ■ Only compute top_three_orders for customer_id=1 ■ This can be much faster! ■ Can make use of index(customer_id)

50

MariaDB - MySQL Comparison

MariaDB Foundation https://mariadb.org

slide-51
SLIDE 51
  • This talk would not have been possible if it not for the MariaDB

Foundation's sponsors.

51

Sponsors of MariaDB Foundation

MariaDB Foundation https://mariadb.org

slide-52
SLIDE 52

Thank you!

Contact details: vicentiu@mariadb.org About: https://mariadb.org/vicentiu

52 MariaDB Foundation https://mariadb.org