I want to add partition to my innoDB table. I have tried to search the syntax for this, but have not found specifics.
Is this syntax wrong? :
ALTER TABLE Product PARTITION BY HASH(catetoryID1) PARTITIONS 6
SUBPARTITION BY KEY(catetoryID2) SUBPARTITIONS 10;
Does SUBPARTITIONS 10 mean each main partition has 10 subpartitions, or does it mean all main partitions have 10 subpartitions divided among them?
It's strange you didn't find the syntax. The MySQL online documentation has quite detailed syntax listed for most common operations.
Look here for overall syntax of the alter table to work with partitions:
http://dev.mysql.com/doc/refman/5.5/en/create-table.html
The syntax for partition management would remain same even when used with the alter table statement, with a few nuances that are listed on the alter table syntax pages in the MySQL docs.
To answer your first question, the problem is not your syntax but rather that you are trying sub-partition a table partitioned first by Hash partitioning - this is not allowed, at least in MySQL 5.5. Only Range or List partitions can be sub-partitioned.
Look here for a complete list of partitioning types:
http://dev.mysql.com/doc/refman/5.5/en/partitioning-types.html
As for the second question, assuming what you were trying would work, you'd be creating 6 partitions hashed by catetoryID1, and then within these you'd have 10 sub-partitions hashed by catetoryID2. So you'd have in all
6 x 10 = 60 partitions
Rules of thumb:
SUBPARTITION is useless. It provides no speed, and nothing else.
Due to various inefficiencies, don't have more than about 50 partitions.
PARTITION BY RANGE is the only useful one.
Often an INDEX can provide better performance than PARTITION; let's see your SELECT.
My blog on partitioning: http://mysql.rjweb.org/doc.php/partitionmaint
Related
My question is with regard to understanding the fate of index after a partition is dropped.
After the partition is dropped, what will happen to the index? And again if there is data inserted to the same truncated partition how will the index work?
I understand that there are only locally created indexes in mysql and only the truncated partition's index is affected
Any thoughts on the same will be greatly appreciated
Indexes will be removed too:
Important
Partitioning applies to all data and indexes of a table; you cannot partition only the data and not the indexes, or vice versa, nor can you partition only a portion of the table.
https://dev.mysql.com/doc/refman/5.5/en/partitioning-overview.html
I've partitioned tables in my MySQL 5.1.41 which hold very huge amount of data. Recently, I've deleted a lot of data which caused fragmentation of around 500 GB yet there is a lot of data in the partitions.
To reclaim that space to the OS, I had to de-fragment the partitions. I referred to MySQL documentation, https://dev.mysql.com/doc/refman/5.1/en/partitioning-maintenance.html which confused me with the following statements,
Rebuilding partitions : Rebuilds the partition; this has the same effect as dropping all records stored in the partition, then
reinserting them. This can be useful for purposes of defragmentation.
Optimizing partitions : If you have deleted a large number of rows from a partition or if you have made many changes to a partitioned
table with variable-length rows (that is, having VARCHAR, BLOB, or
TEXT columns), you can use ALTER TABLE ... OPTIMIZE PARTITION to
reclaim any unused space and to defragment the partition data file.
I tried both and observed sometimes "rebuild" happens faster and sometimes "optimize". Each partition I run these commands on, has records from millions to sometimes billions. I'm aware of what MySQL does for above each statement.
Do they need to be applied based on number of rows in the partition? If so, on how many rows I can use "optimize" and on how many I should use "rebuild"?
Also, which is better to use?
MyISAM or InnoDB? (The answer will be different.)
For MyISAM, REBUILD/REORGANIZE/OPTIMIZE will take about the same effort per partition.
For InnoDB, OPTIMIZE PARTITION rebuilds all partitions. So, don't use this if you want to do the partitions one at a time. REORGANIZE PARTITION of the partition into an identical partition definition should act only on the one partition. I recommend that.
It is generally not worth using partitioning unless you have a least a million rows. Also BY RANGE is the only form that has any performance benefits that I have found.
Perhaps the main use of partitioning is with a time-series where you want to delete "old" data. PARTITION BY RANGE with weekly or monthly partitions lets you very efficiently DROP PARTITION rather than DELETE. More in my blog.
(My answer applies to all versions through 5.7, not just your antique 5.1.)
I have a large table with about 40 partition.
Each partition belongs to different area data.
I found that some partition are crashed and i also want to work on other partitions at the same time keeping crashed partitions as it is.
So can i query on other partition, using PARTITION in SELECT statement, when some partitions are crashed?
I would appreciate if somebody helps me. Thanks in advance
You can, in some sense, restrict select statements to certain partitions. There's no parameter that allow to select a partition (wouldn't make sense since partition access is controlled by the partitioning limits) but you can write your query so that it only retrieves data from specific partitions. For instance if you have partitioned by date you can use a WHERE clause that only addresses specific dates, working so only with specific partitions.
We are facing issues with uneven distribution of data across key partitions. The partition key is a UUID column. When we create 36 partitions, only 9 partitions are populated and when we create 100 partitions, only 25 partitions get populated. What could be the cause of that ? Is there some issue with MYSQL key partition while working with UUIDs?
Also, is there a way to customize the MYSQL key partitioning implementation so that we could use something like mod(crc32(),36)
Thanks for your help.
Prikshat
I have a database partitioned by range on to_days(created_at).
The partitions are monthly (p1 - p50) with a pmax catchall on the end. In the below example, I'm expecting only partition p45 to be hit.
when I do an explain partitions select * from units where created_at > "2013-01-01 00:00:00" and NOW()
I get p1,p45 listed under the partitions column
This happens in both 5.1 and 5.5
Why is the optimizer including the first partition for an inequality check?
You asked this a long time ago, but I also ran into this issue and found a workaround here:
http://datacharmer.blogspot.com/2010/05/two-quick-performance-tips-with-mysql.html
... basically you should create a first partition that contains values less than (0), which will always be empty. The MySQL query optimizer will still include this first partition, but at the least it shouldn't be doing any resource-intensive scanning.
UPDATE: Here's a short summary of the URL linked in my original answer:
The official MySQL bugtracker acknowledges this behavior as a feature:
Bug Description:
Regardless of the range in the BETWEEN clause a table partitioned by RANGE using TO_DAYS function always includes the first partition in the table when pruning.
Response:
This is not a bug, since TO_DAYS() returns NULL for invalid dates, it needs to scan the first partition as well (since that holds all NULL values) for ranges.
...
A performance workaround is to create a specific partition to hold all NULL values (like '... LESS THAN (0)'), which also would catch all bad dates.