boost performance with mysql 5.1 partitions

106
Giuseppe Maxia MySQL Community Team Lead Sun Microsystems Boost performance with MySQL 5.1 partitions

Upload: giuseppe-maxia

Post on 17-Dec-2014

10.537 views

Category:

Technology


4 download

DESCRIPTION

How to increase performance using MySQL 5.1 partitions

TRANSCRIPT

Page 1: Boost performance with MySQL 5.1 partitions

Giuseppe MaxiaMySQL Community Team LeadSun Microsystems

Boost performance with MySQL 5.1 partitions

Page 2: Boost performance with MySQL 5.1 partitions

Who's this guy?

about me2

Page 3: Boost performance with MySQL 5.1 partitions

Giuseppe Maxia• a.k.a. The Data Charmer• MySQL Community Team Lead• Long time hacking with MySQL features• Formerly, database consultant, designer, coder.• A passion for QA• An even greater passion for open source• ... and community• Passionate blogger• http://datacharmer.blogspot.com 3

Page 4: Boost performance with MySQL 5.1 partitions

MySQL 5.1 GA

4

Page 5: Boost performance with MySQL 5.1 partitions

MySQL 5.1 GA

5

Page 6: Boost performance with MySQL 5.1 partitions

MySQL 5.1 GA

5

Page 7: Boost performance with MySQL 5.1 partitions

Defining the problem

YOURNEEDS

6

Page 8: Boost performance with MySQL 5.1 partitions

The problem(s)• Too much data• Not enough RAM• Historical data• Growing data• Rotating data

7

Page 9: Boost performance with MySQL 5.1 partitions

Too much data

8

data

Page 10: Boost performance with MySQL 5.1 partitions

Not enough RAM

9

data

RAM

INDEXESINDEXES

Page 11: Boost performance with MySQL 5.1 partitions

Not enough RAM

10

dataRAMINDEXES

INDEXES

Page 12: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

WHAT11

Page 13: Boost performance with MySQL 5.1 partitions

What is it?• Logical splitting of tables• Transparent to user

12

Page 14: Boost performance with MySQL 5.1 partitions

Logical splitting• No need to create separate tables• No need to move chunks of data across files

13

Page 15: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

TRANSPARENT

14

SQL

Page 16: Boost performance with MySQL 5.1 partitions

MERGE TABLE

COMPARED TO MERGE TABLES

15

• separate tables• risk of duplicates• insert in each table• no constraints

Page 17: Boost performance with MySQL 5.1 partitions

PARTITIONED TABLE

COMPARED TO MERGE TABLES

16

• One table• No risk of duplicates• insert in one table• constraints enforced

Page 18: Boost performance with MySQL 5.1 partitions

Wait a minute ...• WHAT THE HELL DOES "LOGICAL SPLIT"

REALLY MEANS?• LET ME EXPLAIN ...

17

Page 19: Boost performance with MySQL 5.1 partitions

Physical partitioning (1)• Take a map

18

Page 20: Boost performance with MySQL 5.1 partitions

Physical partitioning (2)• cut it into pieces

19

Page 21: Boost performance with MySQL 5.1 partitions

Physical partitioning (3)• What you have, is several different pieces

20

Page 22: Boost performance with MySQL 5.1 partitions

Physical partitioning (4)• If you want the map back, you need some

application (adhesive tape) and you may get it wrong

21

Page 23: Boost performance with MySQL 5.1 partitions

Logical partitioning (1)• Take a map

22

Page 24: Boost performance with MySQL 5.1 partitions

Logical partitioning (2)• fold it to show the piece you need

23

Page 25: Boost performance with MySQL 5.1 partitions

Logical partitioning (3)• what you have is still a map, even if you see only

one part.

24

Page 26: Boost performance with MySQL 5.1 partitions

Logical partitioning (4)• if you unfold the map, you still have the whole thing

25

Page 27: Boost performance with MySQL 5.1 partitions

What partitions can do• logical split• but you can also split the data physically• granular partition (subpartitioning)• different methods (range, list, hash, key)

26

Page 28: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

WHY27

Page 29: Boost performance with MySQL 5.1 partitions

4 main reasons to use partitions• To make single inserts and selects faster• To make range selects faster• To help split the data across different paths• To store historical data efficiently• If you need to delete large chunks of data

INSTANTLY

28

Page 30: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

HOW29

Page 31: Boost performance with MySQL 5.1 partitions

HOW TO MAKE PARTITIONS

30

Page 32: Boost performance with MySQL 5.1 partitions

HOW TO MAKE PARTITIONS

•RTFM ...

30

Page 33: Boost performance with MySQL 5.1 partitions

HOW TO MAKE PARTITIONS

•RTFM ...• No, seriously, the manual has everything

30

Page 34: Boost performance with MySQL 5.1 partitions

HOW TO MAKE PARTITIONS

•RTFM ...• No, seriously, the manual has everything• But if you absolutely insist ...

30

Page 35: Boost performance with MySQL 5.1 partitions

HOW TO MAKE PARTITIONSCREATE TABLE t1 ( id int ) ENGINE=InnoDB # or MyISAM, ARCHIVEPARTITION BY RANGE (id)( PARTITION P1 VALUES LESS THAN (10), PARTITION P2 VALUES LESS THAN (20)) 31

Page 36: Boost performance with MySQL 5.1 partitions

HOW TO MAKE PARTITIONSCREATE TABLE t1 ( id int ) ENGINE=InnoDB PARTITION BY LIST (id)( PARTITION P1 VALUES IN (1,2,4), PARTITION P2 VALUES IN (3,5,9))

32

Page 37: Boost performance with MySQL 5.1 partitions

HOW TO MAKE PARTITIONSCREATE TABLE t1 ( id int not null primary key) ENGINE=InnoDB PARTITION BY HASH (id)PARTITIONS 10;

33

Page 38: Boost performance with MySQL 5.1 partitions

HOW TO MAKE PARTITIONSCREATE TABLE t1 ( id int not null primary key) ENGINE=InnoDB PARTITION BY KEY ()PARTITIONS 10;

34

Page 39: Boost performance with MySQL 5.1 partitions

Limitations• Can partition only by INTEGER columns• OR you can partition by an expression, which must

return an integer• Maximum 1024 partitions

• If you have a Unique Key or PK, the partition column must be part of that key

• No Foreign Key support• No Fulltext or GIS support

35

Page 40: Boost performance with MySQL 5.1 partitions

PARTITIONING BY DATECREATE TABLE t1 ( d date) ENGINE=InnoDB PARTITION BY RANGE (year(d))( PARTITION P1 VALUES LESS THAN (1999), PARTITION P2 VALUES LESS THAN (2000))

36

Page 41: Boost performance with MySQL 5.1 partitions

PARTITIONING BY DATECREATE TABLE t1 ( d date) ENGINE=InnoDB PARTITION BY RANGE (to_days(d))( PARTITION P1 VALUES LESS THAN (to_days('1999-01-01')), PARTITION P2 VALUES LESS THAN (to_days('2000-01-01')))

37

Page 42: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

Partition pruning

38

Page 43: Boost performance with MySQL 5.1 partitions

Partition pruning 1a - unpartitioned table - SINGLE RECORD

select * from table_name where colx = 120

Page 44: Boost performance with MySQL 5.1 partitions

Partition pruning 1a - unpartitioned table - SINGLE RECORD

select * from table_name where colx = 120

INDEX

DATA

Page 45: Boost performance with MySQL 5.1 partitions

Partition pruning 1b - unpartitioned table - SINGLE RECORD

select * from table_name where colx = 350

Page 46: Boost performance with MySQL 5.1 partitions

Partition pruning 1c - unpartitioned table - RANGE

select * from table_name where colx between 120 and 230

Page 47: Boost performance with MySQL 5.1 partitions

Partition pruning 2a - table partitioned by colx - SINGLE REC

select * from table_name where colx = 120

100-199

1-99

200-299

300-399

400-499

500-599

Page 48: Boost performance with MySQL 5.1 partitions

Partition pruning 2a - table partitioned by colx - SINGLE REC

select * from table_name where colx = 120

DATA I

NDEX

100-199

1-99

200-299

300-399

400-499

500-599

Page 49: Boost performance with MySQL 5.1 partitions

Partition pruning 2b - table partitioned by colx - SINGLE REC

select * from table_name where colx = 350

100-199

1-99

200-299

300-399

400-499

500-599

Page 50: Boost performance with MySQL 5.1 partitions

Partition pruning 2c - table partitioned by colx - RANGE

100-199

1-99

200-299

300-399

400-499

500-599

select * from table_name where colx between 120 and 230

Page 51: Boost performance with MySQL 5.1 partitions

Partition pruning

EXPLAINselect * from table_name where colx = 120

EXPLAIN PARTITIONSselect * from table_name where colx = 120

in 5.1

before

Page 52: Boost performance with MySQL 5.1 partitions

Partition pruning - not using partition columnexplain partitions select count(*) from table_name where colx=120\G***** 1. row **** id: 1 select_type: SIMPLE table: table_name partitions: p01,p02,p03,p04,p05,p06,p07,p08,p09,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19 type: index...

Page 53: Boost performance with MySQL 5.1 partitions

explain partitions select count(*) from table_name where colx between 120 and 230\G***** 1. row **** id: 1 select_type: SIMPLE table: table_name partitions: p01,p02,p03,p04,p05,p06,p07,p08,p09,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19 type: index...

Partition pruning - not using partition column

Page 54: Boost performance with MySQL 5.1 partitions

Partition pruning - table partitioned by colxexplain partitions select count(*) from table_name where colx between 120 and 230\G***** 1. row **** id: 1 select_type: SIMPLE table: table_name partitions: p02,p03 type: index...

Page 55: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

WHEN51

Page 56: Boost performance with MySQL 5.1 partitions

When to use partitions?• if you have large tables• if you know that you will always query for the

partitioning column• if you have historical tables that you want to purge

quickly• if your indexes are larger than the available RAM

52

Page 57: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

HANDS ON

53

Page 58: Boost performance with MySQL 5.1 partitions

components used for testing

54

Page 59: Boost performance with MySQL 5.1 partitions

components used for testing• MySQL Sandbox

> created MySQL instances in seconds> http://launchpad.net/mysql-sandbox

54

Page 60: Boost performance with MySQL 5.1 partitions

components used for testing• MySQL Sandbox

> created MySQL instances in seconds> http://launchpad.net/mysql-sandbox

• MySQL Employees Test Database> has ~ 4 mil records in 6 tables> http://launchpad.net/test-db

54

Page 61: Boost performance with MySQL 5.1 partitions

components used for testing• MySQL Sandbox

> created MySQL instances in seconds> http://launchpad.net/mysql-sandbox

• MySQL Employees Test Database> has ~ 4 mil records in 6 tables> http://launchpad.net/test-db

• Command line ability> fingers> ingenuity

54

Page 62: Boost performance with MySQL 5.1 partitions

55

employees test database

Page 63: Boost performance with MySQL 5.1 partitions

How many partitionsfrom information_schema.partitions +-------+-----------------+----------+| pname | expr | descr | +-------+-----------------+----------+| p01 | year(from_date) | 1985 | | p02 | year(from_date) | 1986 |

... | p13 | year(from_date) | 1997 | | p14 | year(from_date) | 1998 | | p15 | year(from_date) | 1999 | | p16 | year(from_date) | 2000 | ...| p19 | year(from_date) | MAXVALUE | +-------+-----------------+----------+

56

Page 64: Boost performance with MySQL 5.1 partitions

How many recordsselect count(*) from salaries; +----------+ | count(*) | +----------+ | 2844047 | +----------+1 row in set (0.01 sec)

57

Page 65: Boost performance with MySQL 5.1 partitions

How many records in 1998 not partitionedselect count(*) from salaries where from_date between '1998-01-01' and '1998-12-31';+----------+| count(*) |+----------+| 247489 | +----------+1 row in set (1.52 sec)

# NOT PARTITIONED 58

Page 66: Boost performance with MySQL 5.1 partitions

How many records in 1998PARTITIONEDselect count(*) from salaries where from_date between '1998-01-01' and '1998-12-31';+----------+| count(*) |+----------+| 247489 | +----------+1 row in set (0.41 sec)

# partition p1559

Page 67: Boost performance with MySQL 5.1 partitions

How many records in 1999not partitionedselect count(*) from salaries where from_date between '1999-01-01' and '1999-12-31';+----------+| count(*) |+----------+| 260957 |+----------+1 row in set (1.54 sec)

# NOT PARTITIONED60

Page 68: Boost performance with MySQL 5.1 partitions

How many records in 1999PARTITIONEDselect count(*) from salaries where from_date between '1999-01-01' and '1999-12-31';+----------+| count(*) |+----------+| 260957 |+----------+1 row in set (0.17 sec)

# partition p1661

Page 69: Boost performance with MySQL 5.1 partitions

Deleting 1998 records not partitioneddelete from salaries where from_date between '1998-01-01' and '1998-12-31';Query OK, 247489 rows affected (19.13 sec)

# NOT PARTITIONED

62

Page 70: Boost performance with MySQL 5.1 partitions

Deleting 1998 records partitionedalter table salaries drop partition p15;Query OK, 0 rows affected (1.35 sec)

63

Page 71: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

LEVERAGINGREPLICATION

64

Page 72: Boost performance with MySQL 5.1 partitions

Replication schemes

65

SLAVESLAVE

MASTER

INNODBNOTPARTITIONED

INNODBPARTITIONEDBY RANGE

MyISAMPARTITIONEDBY RANGE

concurrent insert

concurrent batch processing large batch processing

SLAVE

INNODBNOTPARTITIONED

concurrent read

Page 73: Boost performance with MySQL 5.1 partitions

Replication schemes

66

SLAVESLAVE

MASTER

INNODBPARTITIONED

MyISAMPARTITIONED

INNODBNONPARTITIONED

concurrent insert

concurrent readsbatch processing

Page 74: Boost performance with MySQL 5.1 partitions

Replication schemes - dimensions

67

MASTER

INNODBNOTPARTITIONED

ARCHIVEPARTITIONEDBY RANGE (date)

ARCHIVEPARTITIONEDBY RANGE (product)

concurrent insert

dimensional processing dimensional processing

SLAVE

ARCHIVEPARTITIONEDBY RANGE (locations)

dimensional processing

SLAVESLAVE

Page 75: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

PITFALLS68

Page 76: Boost performance with MySQL 5.1 partitions

Expressions• Partition by function• Search by column

69

Page 77: Boost performance with MySQL 5.1 partitions

WRONG

70

PARTITION BY RANGE(year(from_date))

select count(*) from salaries where year(from_date) = 1998;+----------+| count(*) |+----------+| 247489 | +----------+1 row in set (2.25 sec)

Page 78: Boost performance with MySQL 5.1 partitions

RIGHT

71

PARTITION BY RANGE(year(from_date))

select count(*) from salaries where from_date between '1998-01-01' and '1998-12-31';+----------+| count(*) |+----------+| 247489 | +----------+1 row in set (0.46 sec)

Page 79: Boost performance with MySQL 5.1 partitions

EXPLAIN

72

explain partitions select count(*) from salaries where year(from_date) = 1998\G***** 1. row **** id: 1 select_type: SIMPLE table: salaries partitions: p01,p02,p03,p04,p05,p06,p07,p08,p09,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19 type: index...

Page 80: Boost performance with MySQL 5.1 partitions

EXPLAIN

73

explain partitions select count(*) from salaries where from_date between '1998-01-01' and '1998-12-31'\G***** 1. row **** id: 1 select_type: SIMPLE table: salaries partitions: p14,p15...

Page 81: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

BENCHMARKS

74

Page 82: Boost performance with MySQL 5.1 partitions

Partitions benchmarks (laptop)

engine storage (MB)

innodb 221myisam 181archive 74innodb partitioned (whole) 289innodb partitioned (file per table) 676myisam partitioned 182archive partitioned 72

Page 83: Boost performance with MySQL 5.1 partitions

Benchmarking results (laptop)engine query year

2000query year 2002

InnoDB 1.25 1.25

MyISAM 1.72 1.73

Archive 2.47 2.45

InnoDB partitioned whole

0.24 0.10

InnoDB Partitioned (file per table)

0.45 0.10

MyISAM partitioned 0.18 0.12

Archive partitioned 0.22 0.12

Page 84: Boost performance with MySQL 5.1 partitions

Partitioning storage (huge server)

engine storage (GB)

innodb (with PK) 330myisam (with PK) 141archive 13innodb partitioned (no PK) 237myisam partitioned (no PK) 107archive partitioned 13

Page 85: Boost performance with MySQL 5.1 partitions

Benchmarking results (huge server)engine 6 month rangeInnoDB 4 min 30sMyISAM 25.03sArchive 22 min 25sInnoDB partitioned by month 13.19MyISAM partitioned by year 6.31MyISAM partitioned by month 4.45Archive partitioned by year 16.67Archive partitioned by month 8.97

Page 86: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

TOOLS79

Page 87: Boost performance with MySQL 5.1 partitions

The partition helper• The INFORMATION_SCHEMA.PARTITIONS table• The partition helper

> http://datacharmer.blogspot.com/2008/12/partition-helper-improving-usability.html

> A Perl script that creates partitioning statements

• ... anything you are creating right now :)

80

Page 88: Boost performance with MySQL 5.1 partitions

the partition helper./partitions_helper \ --table=mytable --column=prod_id \ --interval=1000 --start=1 --end=10000

ALTER TABLE mytable PARTITION by range (prod_id)( partition p001 VALUES LESS THAN (1000), partition p002 VALUES LESS THAN (2000), partition p003 VALUES LESS THAN (3000), partition p004 VALUES LESS THAN (4000), partition p005 VALUES LESS THAN (5000), partition p006 VALUES LESS THAN (6000), partition p007 VALUES LESS THAN (7000), partition p008 VALUES LESS THAN (8000), partition p009 VALUES LESS THAN (9000), partition p010 VALUES LESS THAN (10000)); 81

Page 89: Boost performance with MySQL 5.1 partitions

the partition helper./partitions_helper --table=mytable --column=d --interval=year \ --start=2004-01-01 --end=2009-01-01

ALTER TABLE mytable PARTITION by range (to_date(d))( partition p001 VALUES LESS THAN (to_days('2004-01-01')), partition p002 VALUES LESS THAN (to_days('2005-01-01')), partition p003 VALUES LESS THAN (to_days('2006-01-01')), partition p004 VALUES LESS THAN (to_days('2007-01-01')), partition p005 VALUES LESS THAN (to_days('2008-01-01')), partition p006 VALUES LESS THAN (to_days('2009-01-01')));

82

Page 90: Boost performance with MySQL 5.1 partitions

the partition helper./partitions_helper --table=mytable \ --column=d --interval=month \ --start=2008-01-01 --end=2009-01-01

ALTER TABLE mytable PARTITION by range (to_date(d))( partition p001 VALUES LESS THAN (to_days('2008-01-01')), partition p002 VALUES LESS THAN (to_days('2008-02-01')), partition p003 VALUES LESS THAN (to_days('2008-03-01')), partition p004 VALUES LESS THAN (to_days('2008-04-01')), partition p005 VALUES LESS THAN (to_days('2008-05-01')), partition p006 VALUES LESS THAN (to_days('2008-06-01')), partition p007 VALUES LESS THAN (to_days('2008-07-01')), partition p008 VALUES LESS THAN (to_days('2008-08-01')), partition p009 VALUES LESS THAN (to_days('2008-09-01')), partition p010 VALUES LESS THAN (to_days('2008-10-01')), partition p011 VALUES LESS THAN (to_days('2008-11-01')), partition p012 VALUES LESS THAN (to_days('2008-12-01')), partition p013 VALUES LESS THAN (to_days('2009-01-01')));

83

Page 91: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

TIPS84

Page 92: Boost performance with MySQL 5.1 partitions

TIPS• For large table ( indexes > available RAM)

> DO NOT USE INDEXES> PARTITIONS ARE MORE EFFICIENT

85

Page 93: Boost performance with MySQL 5.1 partitions

TIPS• Before adopting partitions in production, benchmark!• you can create partitions of different sizes

> in historical tables, you can partition – current data by day– recent data by month– distant past data by year

> ALL IN THE SAME TABLE!• If you want to enforce a constraint on a integer

column, you may set a partition by list, with only the values you want to admit.

86

Page 94: Boost performance with MySQL 5.1 partitions

TIPS• For large historical tables, consider using ARCHIVE

+ partitions> You see benefits for very large amounts of data ( > 500

MB)> Very effective when you run statistics> Almost the same performance of MyISAM> but 1/10 of storage

87

Page 96: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

BONUS SLIDES

89

Page 97: Boost performance with MySQL 5.1 partitions

MySQL 5.1 partitions

ANNOYANCES90

Page 98: Boost performance with MySQL 5.1 partitions

Annoyances with partitions

91

• CREATE TABLE STATEMENT hard to read

Page 99: Boost performance with MySQL 5.1 partitions

Annoyances with partitions

91

• CREATE TABLE STATEMENT hard to read

Page 100: Boost performance with MySQL 5.1 partitions

Annoyances with partitions• hard to read (FIXED!! in 5.1.31)

92

Page 101: Boost performance with MySQL 5.1 partitions

Annoyances with partitions• hard to read (FIXED!! in 5.1.31)

92

Page 102: Boost performance with MySQL 5.1 partitions

Annoyances with partitions• CREATE TABLE only keeps the result of the

expression for each partition.• (you can use the information_schema to ease the

pain in this case)

93

Page 103: Boost performance with MySQL 5.1 partitions

Annoyances with partitions

94

CREATE TABLE t1 ( d date) ENGINE=InnoDB PARTITION BY RANGE (to_days(d))( PARTITION P1 VALUES LESS THAN (to_days('1999-01-01')), PARTITION P2 VALUES LESS THAN (to_days('2000-01-01')))

Page 104: Boost performance with MySQL 5.1 partitions

Annoyances with partitions

95

CREATE TABLE `t1` ( `d` date DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1/*!50100 PARTITION BY RANGE (to_days(d))(PARTITION P1 VALUES LESS THAN (730120) ENGINE = InnoDB, PARTITION P2 VALUES LESS THAN (730485) ENGINE = InnoDB) */

Page 105: Boost performance with MySQL 5.1 partitions

Fixing annoyances with partitions

96

select partition_name part, partition_expression expr, partition_description val from information_schema.partitions where table_name='t1';+------+------------+--------+| part | expr | val |+------+------------+--------+| P1 | to_days(d) | 730120 | | P2 | to_days(d) | 730485 | +------+------------+--------+

Page 106: Boost performance with MySQL 5.1 partitions

fixing annoyances with partitions

97

select partition_name part , partition_expression expr, from_days(partition_description) val from information_schema.partitions where table_name='t1';+------+------------+------------+| part | expr | val |+------+------------+------------+| P1 | to_days(d) | 1999-01-01 | | P2 | to_days(d) | 2000-01-01 | +------+------------+------------+