Top Banner
March 19, 2009 Giuseppe Maxia MySQL Community Team Lead Sun Microsystems Boost performance with MySQL 5.1 partitions
89
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Boost Performance With  My S Q L 51 Partitions

March 19, 2009Giuseppe MaxiaMySQL Community Team LeadSun Microsystems

Boost performance with MySQL 5.1 partitions

Page 2: Boost Performance With  My S Q L 51 Partitions

Who's this guy?

about me2

Page 3: Boost Performance With  My S Q L 51 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  My S Q L 51 Partitions

MySQL 5.1 GA

4

Page 5: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 GA

5

Page 6: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 GA

5

Page 7: Boost Performance With  My S Q L 51 Partitions

Defining the problem

YOURNEEDS

6

Page 8: Boost Performance With  My S Q L 51 Partitions

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

7

Page 9: Boost Performance With  My S Q L 51 Partitions

Too much data

8

data

Page 10: Boost Performance With  My S Q L 51 Partitions

Not enough RAM

9

data

RAM

INDEXESINDEXES

Page 11: Boost Performance With  My S Q L 51 Partitions

Not enough RAM

10

dataRAMINDEXES

INDEXES

Page 12: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 partitions

WHAT11

Page 13: Boost Performance With  My S Q L 51 Partitions

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

12

Page 14: Boost Performance With  My S Q L 51 Partitions

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

13

Page 15: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 partitions

TRANSPARENT

14

SQL

Page 16: Boost Performance With  My S Q L 51 Partitions

MERGE TABLE

COMPARED TO MERGE TABLES

15

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

Page 17: Boost Performance With  My S Q L 51 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  My S Q L 51 Partitions

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

REALLY MEANS?• LET ME EXPLAIN ...

17

Page 19: Boost Performance With  My S Q L 51 Partitions

Physical partitioning (1)• Take a map

18

Page 20: Boost Performance With  My S Q L 51 Partitions

Physical partitioning (2)• cut it into pieces

19

Page 21: Boost Performance With  My S Q L 51 Partitions

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

20

Page 22: Boost Performance With  My S Q L 51 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  My S Q L 51 Partitions

Logical partitioning (1)• Take a map

22

Page 24: Boost Performance With  My S Q L 51 Partitions

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

23

Page 25: Boost Performance With  My S Q L 51 Partitions

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

one part.

24

Page 26: Boost Performance With  My S Q L 51 Partitions

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

25

Page 27: Boost Performance With  My S Q L 51 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  My S Q L 51 Partitions

MySQL 5.1 partitions

WHY27

Page 29: Boost Performance With  My S Q L 51 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  My S Q L 51 Partitions

MySQL 5.1 partitions

HOW29

Page 31: Boost Performance With  My S Q L 51 Partitions

HOW TO MAKE PARTITIONS

30

Page 32: Boost Performance With  My S Q L 51 Partitions

HOW TO MAKE PARTITIONS

•RTFM ...

30

Page 33: Boost Performance With  My S Q L 51 Partitions

HOW TO MAKE PARTITIONS

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

30

Page 34: Boost Performance With  My S Q L 51 Partitions

HOW TO MAKE PARTITIONS

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

30

Page 35: Boost Performance With  My S Q L 51 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  My S Q L 51 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  My S Q L 51 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  My S Q L 51 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  My S Q L 51 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  My S Q L 51 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  My S Q L 51 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  My S Q L 51 Partitions

MySQL 5.1 partitions

WHEN38

Page 43: Boost Performance With  My S Q L 51 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

39

Page 44: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 partitions

HANDS ON

40

Page 45: Boost Performance With  My S Q L 51 Partitions

components used for testing

41

Page 46: Boost Performance With  My S Q L 51 Partitions

components used for testing• MySQL Sandbox

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

41

Page 47: Boost Performance With  My S Q L 51 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

41

Page 48: Boost Performance With  My S Q L 51 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

41

Page 49: Boost Performance With  My S Q L 51 Partitions

42

employees test database

Page 50: Boost Performance With  My S Q L 51 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 | +-------+-----------------+----------+

43

Page 51: Boost Performance With  My S Q L 51 Partitions

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

44

Page 52: Boost Performance With  My S Q L 51 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 45

Page 53: Boost Performance With  My S Q L 51 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 p1546

Page 54: Boost Performance With  My S Q L 51 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 PARTITIONED47

Page 55: Boost Performance With  My S Q L 51 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 p1648

Page 56: Boost Performance With  My S Q L 51 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

49

Page 57: Boost Performance With  My S Q L 51 Partitions

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

50

Page 58: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 partitions

LEVERAGINGREPLICATION

51

Page 59: Boost Performance With  My S Q L 51 Partitions

Replication schemes

52

SLAVESLAVE

MASTER

INNODBNOTPARTITIONED

INNODBPARTITIONEDBY RANGE

MyISAMPARTITIONEDBY RANGE

concurrent insert

concurrent batch processing large batch processing

SLAVE

INNODBNOTPARTITIONED

concurrent read

Page 60: Boost Performance With  My S Q L 51 Partitions

Replication schemes

53

SLAVESLAVE

MASTER

INNODBPARTITIONED

MyISAMPARTITIONED

INNODBNONPARTITIONED

concurrent insert

concurrent readsbatch processing

Page 61: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 partitions

PITFALLS54

Page 62: Boost Performance With  My S Q L 51 Partitions

Expressions• Partition by function• Search by column

55

Page 63: Boost Performance With  My S Q L 51 Partitions

WRONG

56

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 64: Boost Performance With  My S Q L 51 Partitions

RIGHT

57

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 65: Boost Performance With  My S Q L 51 Partitions

EXPLAIN

58

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 66: Boost Performance With  My S Q L 51 Partitions

EXPLAIN

59

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 67: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 partitions

BENCHMARKS

60

Page 68: Boost Performance With  My S Q L 51 Partitions

Partitions benchmarks (laptop)

engine storage (MB)

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

Page 69: Boost Performance With  My S Q L 51 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 70: Boost Performance With  My S Q L 51 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 71: Boost Performance With  My S Q L 51 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 72: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 partitions

TOOLS65

Page 73: Boost Performance With  My S Q L 51 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 :)

66

Page 74: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 partitions

TIPS67

Page 75: Boost Performance With  My S Q L 51 Partitions

TIPS• For large table ( indexes > available RAM)

> DO NOT USE INDEXES> PARTITIONS ARE MORE EFFICIENT

68

Page 76: Boost Performance With  My S Q L 51 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.

69

Page 77: Boost Performance With  My S Q L 51 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

70

Page 79: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 partitions

BONUS SLIDES

72

Page 80: Boost Performance With  My S Q L 51 Partitions

MySQL 5.1 partitions

ANNOYANCES73

Page 81: Boost Performance With  My S Q L 51 Partitions

Annoyances with partitions

74

• CREATE TABLE STATEMENT hard to read

Page 82: Boost Performance With  My S Q L 51 Partitions

Annoyances with partitions

74

• CREATE TABLE STATEMENT hard to read

Page 83: Boost Performance With  My S Q L 51 Partitions

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

75

Page 84: Boost Performance With  My S Q L 51 Partitions

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

75

Page 85: Boost Performance With  My S Q L 51 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)

76

Page 86: Boost Performance With  My S Q L 51 Partitions

Annoyances with partitions

77

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 87: Boost Performance With  My S Q L 51 Partitions

Annoyances with partitions

78

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 88: Boost Performance With  My S Q L 51 Partitions

Fixing annoyances with partitions

79

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 89: Boost Performance With  My S Q L 51 Partitions

fixing annoyances with partitions

80

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 | +------+------------+------------+