简体   繁体   中英

Partition MySQL table with primary key and concatonated unique index

I have a table storing weekly viewing statistic for around 40K businesses, the tables passed 2.2M records and is starting to slow things down, I'm looking at partitioning it to speed things up but I'm not sure how best to do it.

My ORM requires an id field as a primary key, but that field has no relevance to the data, I've been using a unique index on fields for year, week number and business ID.

As I need the primary key to be involved in the partition map, I'm not sure how best to organise this (I've never used partitioning before).

Currently I have...

    CREATE TABLE `weekly_views` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `business_id` int(11) NOT NULL,
    `year` smallint(4) UNSIGNED NOT NULL,
    `week` tinyint(2) UNSIGNED NOT NULL,
    `hits` int(5) NOT NULL,
    `created` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
    UNIQUE `search` USING BTREE (business_id, `year`, `week`),
    UNIQUE `id` USING BTREE (id, `week`)
) ENGINE=`InnoDB` AUTO_INCREMENT=2287009 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ROW_FORMAT=COMPACT CHECKSUM=0 DELAY_KEY_WRITE=0 PARTITION BY LIST(week) PARTITIONS 52 (PARTITION p1 VALUES IN (1) ENGINE = InnoDB,
 PARTITION p2 VALUES IN (2) ENGINE = InnoDB,
 PARTITION p3 VALUES IN (3) ENGINE = InnoDB,
 PARTITION p4 VALUES IN (4) ENGINE = InnoDB,
(5 ... 51)
 PARTITION p52 VALUES IN (52) ENGINE = InnoDB);

One partition per week seemed the only logical way to break them up. Am I right that when I search for a record for the current week/business using 'business_id = xx and week = xx and year = xx' it's going to know which partition to use without searching them all? But, when I get the result and save it via the ORM, it's going to use the id field and not know which partition to use?

I guess I could use a custom query to insert or update (I haven't originally done this as the ORM doesn't support it).

Am I going the right way about this, or is there a better way to partition a table like this?

Thanks for your help!

As long as the query has week column in WHERE clause, MySQL will look in correct partition. However, weeks repeat each year and you'll end up with data from different years in the same partition.

Also you need 53 not 52 partitions, as you'll need to deal with leap years.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM