Should I defragment InnoDB table with fixed-length fields?What is the difference between optimize table and...
Is layered encryption more secure than long passwords?
If I tried and failed to start my own business, how do I apply for a job without job experience?
Is it possible to detect 100% of SQLi with a simple regex?
Problems with position of tikzpictures in beamer
How can I keep my gold safe from other PCs?
Isn't a semicolon (';') needed after a function declaration in C++?
Is practicing on a digital piano harmful to an experienced piano player?
Is the UK legally prevented from having another referendum on Brexit?
In the Lost in Space intro why was Dr. Smith actor listed as a special guest star?
Sets that are both Sum-free and Product-free
Coworker is trying to get me to sign his petition to run for office. How to decline politely?
How can I give a Ranger advantage on a check due to Favored Enemy without spoiling the story for the player?
Why does a single AND gate need 60 transistors?
Is it possible to narrate a novel in a faux-historical style without alienating the reader?
Including proofs of known theorems in master's thesis
If we can’t finish all tasks, does this mean we are doing Scrum wrong?
Why don't you get burned by the wood benches in a sauna?
How to regain lost focus?
How to deal with an underperforming subordinate?
What is the meaning of "usr"?
How do I purchase a drop bar bike that will be converted to flat bar?
Is having explosions as a go-to solution considered bad table manners?
Coworker asking me to not bring cakes due to self control issue. What should I do?
Could a civilization in medieval fantasy world sustain itself by occupying important trade hubs and taxing trade?
Should I defragment InnoDB table with fixed-length fields?
What is the difference between optimize table and analyze table in mysqlAre two indexes needed?Finding rows for a specified date rangeCalculating employee's work timeAdding index to large mysql tablesWhy are simple SELECTs on InnoDB 100x slower than on MyISAM?Updating a table with a single UPDATE statement vs several UPDATE statementsOptimizing a simple query on a large tableHow to improve query count execution with mySql replicate?Deadlocks appeared after moving to MariaDB10.2 from MySQL5.5Why does the Select statement stalls when executed directly in sequence?
I am running MariaDB 10.2.13 on Linux (Debian).
I am setting up an InnoDB table that will record a lot of data but I will keep only the last one-hour rows. Thus, the number of rows will remain constant.
I should expect on this table:
- many INSERTs
- many UPDATEs
- some DELETE (rows > 1 hour) from time to time
Example:
Table is defined with fixed-length fields only and some indexes.
CREATE TABLE `tbl_log` (
`ip` int(4) unsigned NOT NULL,
`date` datetime NOT NULL,
`external_id` smallint(6) unsigned NOT NULL,
`counter` smallint(6) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`ip`,`external_id`),
KEY `external_id` (`external_id`),
KEY `counter` (`counter`),
KEY `date_idx` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Inserts (and updates, through on duplicate key
) may look like this (ip and external_id will vary):
INSERT INTO tbl_log
SET ip = INET_ATON('192.168.1.1'),
date = now(),
external_id = 123,
counter = 0
ON DUPLICATE KEY UPDATE counter=counter+1;
Finally, deleting old rows will be done with a query:
DELETE FROM tbl_log WHERE date < DATE_SUB(NOW(), INTERVAL 1 HOUR);
Question:
Will such a table fragment over time?
If so, I think I should defragment it. If necessary, I planned to run OPTIMIZE TABLE tbl_log;
(with option innodb-defragment=1
) right after delete...
mysql innodb mariadb fragmentation
bumped to the homepage by Community♦ 1 min ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
I am running MariaDB 10.2.13 on Linux (Debian).
I am setting up an InnoDB table that will record a lot of data but I will keep only the last one-hour rows. Thus, the number of rows will remain constant.
I should expect on this table:
- many INSERTs
- many UPDATEs
- some DELETE (rows > 1 hour) from time to time
Example:
Table is defined with fixed-length fields only and some indexes.
CREATE TABLE `tbl_log` (
`ip` int(4) unsigned NOT NULL,
`date` datetime NOT NULL,
`external_id` smallint(6) unsigned NOT NULL,
`counter` smallint(6) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`ip`,`external_id`),
KEY `external_id` (`external_id`),
KEY `counter` (`counter`),
KEY `date_idx` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Inserts (and updates, through on duplicate key
) may look like this (ip and external_id will vary):
INSERT INTO tbl_log
SET ip = INET_ATON('192.168.1.1'),
date = now(),
external_id = 123,
counter = 0
ON DUPLICATE KEY UPDATE counter=counter+1;
Finally, deleting old rows will be done with a query:
DELETE FROM tbl_log WHERE date < DATE_SUB(NOW(), INTERVAL 1 HOUR);
Question:
Will such a table fragment over time?
If so, I think I should defragment it. If necessary, I planned to run OPTIMIZE TABLE tbl_log;
(with option innodb-defragment=1
) right after delete...
mysql innodb mariadb fragmentation
bumped to the homepage by Community♦ 1 min ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
I am running MariaDB 10.2.13 on Linux (Debian).
I am setting up an InnoDB table that will record a lot of data but I will keep only the last one-hour rows. Thus, the number of rows will remain constant.
I should expect on this table:
- many INSERTs
- many UPDATEs
- some DELETE (rows > 1 hour) from time to time
Example:
Table is defined with fixed-length fields only and some indexes.
CREATE TABLE `tbl_log` (
`ip` int(4) unsigned NOT NULL,
`date` datetime NOT NULL,
`external_id` smallint(6) unsigned NOT NULL,
`counter` smallint(6) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`ip`,`external_id`),
KEY `external_id` (`external_id`),
KEY `counter` (`counter`),
KEY `date_idx` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Inserts (and updates, through on duplicate key
) may look like this (ip and external_id will vary):
INSERT INTO tbl_log
SET ip = INET_ATON('192.168.1.1'),
date = now(),
external_id = 123,
counter = 0
ON DUPLICATE KEY UPDATE counter=counter+1;
Finally, deleting old rows will be done with a query:
DELETE FROM tbl_log WHERE date < DATE_SUB(NOW(), INTERVAL 1 HOUR);
Question:
Will such a table fragment over time?
If so, I think I should defragment it. If necessary, I planned to run OPTIMIZE TABLE tbl_log;
(with option innodb-defragment=1
) right after delete...
mysql innodb mariadb fragmentation
I am running MariaDB 10.2.13 on Linux (Debian).
I am setting up an InnoDB table that will record a lot of data but I will keep only the last one-hour rows. Thus, the number of rows will remain constant.
I should expect on this table:
- many INSERTs
- many UPDATEs
- some DELETE (rows > 1 hour) from time to time
Example:
Table is defined with fixed-length fields only and some indexes.
CREATE TABLE `tbl_log` (
`ip` int(4) unsigned NOT NULL,
`date` datetime NOT NULL,
`external_id` smallint(6) unsigned NOT NULL,
`counter` smallint(6) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`ip`,`external_id`),
KEY `external_id` (`external_id`),
KEY `counter` (`counter`),
KEY `date_idx` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Inserts (and updates, through on duplicate key
) may look like this (ip and external_id will vary):
INSERT INTO tbl_log
SET ip = INET_ATON('192.168.1.1'),
date = now(),
external_id = 123,
counter = 0
ON DUPLICATE KEY UPDATE counter=counter+1;
Finally, deleting old rows will be done with a query:
DELETE FROM tbl_log WHERE date < DATE_SUB(NOW(), INTERVAL 1 HOUR);
Question:
Will such a table fragment over time?
If so, I think I should defragment it. If necessary, I planned to run OPTIMIZE TABLE tbl_log;
(with option innodb-defragment=1
) right after delete...
mysql innodb mariadb fragmentation
mysql innodb mariadb fragmentation
edited Mar 20 '18 at 16:44
RolandoMySQLDBA
142k24223379
142k24223379
asked Mar 20 '18 at 14:35
Nicolas PayartNicolas Payart
69531127
69531127
bumped to the homepage by Community♦ 1 min ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
bumped to the homepage by Community♦ 1 min ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
I would say yes for four(4) major reasons
- Page Boundaries / Index Pages
- Index Layout
- Index Statistics
- Bulk DML
PAGE BOUNDARIES / INDEX PAGES
According to the MySQL Documentation on Limits on InnoDB tables
The maximum row length, except for variable-length columns (VARBINARY, VARCHAR, BLOB and TEXT), is slightly less than half of a page for 4KB, 8KB, 16KB, and 32KB page sizes. For example, the maximum row length for the default innodb_page_size of 16KB is about 8000 bytes. For an InnoDB page size of 64KB, the maximum row length is about 16000 bytes. LONGBLOB and LONGTEXT columns must be less than 4GB, and the total row length, including BLOB and TEXT columns, must be less than 4GB.
Your table uses INT UNSIGNED (4 bytes), DATETIME (8 bytes), 2 SMALLINTs (4 bytes) per row. That's a total of 16 bytes per row. This means you can fit 1000 rows into a single InnoDB page, but there is a very small piece of fragmentation. Using the default innodb_page_size (16K or 16384), there will be 384 bytes of fragmentation with a page. It is most likely used for mapping the data within the one page.
Doing mass INSERTs, DELETEs, and UPDATEs will generate many pages with empty space for whole rows that are marked as unused. This is in addition to the 384 bytes region of the data page.
INDEX LAYOUT
You will generate many index pages
- You have a 6-byte PRIMARY KEY
- Each secondary index carries a copy of the PRIMARY KEY
KEY external_id (external_id),
will be 8 bytes (SMALLINT + PRIMARY KEY)
KEY counter (counter),
will be 8 bytes (SMALLINT + PRIMARY KEY)
KEY date_idx (date)
will be 14 bytes (DATE + PRIMARY KEY)- 36 bytes for indexing a single row
- Indexes are represented as BTREEs, so you are looking at O(n log n) space utilization. If you account for non-leaf page splits, many index pages will be 50% empty (without question).
INDEX STATISTICS
Running INSERTs, DELETEs, and UPDATEs will skew index stats since index cardinalities will frequently change. You need to run ANALYZE TABLE tbl_log;
. Running OPTIMIZE TABLE tbl_log;
will defrag the tables and run ANALYZE TABLE tbl_log;
as the last step (See my post from Feb 27, 2013
: What is the difference between optimize table and analyze table in mysql)
BULK DML
The DELETE query you will be doing by the hour is a bulk operation. Many rows will need a ton of housecleaning to keep up with marking rows deleted.
No, you can't hold 1000 rows per page. There is per-column, per-row, and per-block overheads. You'll be lucky to get 500 rows/block.
– Rick James
Mar 23 '18 at 0:55
DATETIME
is no longer 8 bytes, but only 5 in newer versions.
– Rick James
Mar 23 '18 at 0:57
The PK is 9 bytes, not 6. Hence, all the math about secondary keys is off. Plus there is overhead in secondary key BTrees.
– Rick James
Mar 23 '18 at 0:57
Block splits lead to the BTree being an average of 69% full. This is not bad, and should be ignored.
– Rick James
Mar 23 '18 at 1:00
add a comment |
I say "no" for various reasons.
- The fragmentation will recur promptly after the
OPTIMIZE
, so why bother. - The fragmentation is not that big a deal. The performance issue is minimal. The "depth" of the BTrees rarely changes due to fragmentation.
- InnoDB tends to get rid of fragmentation by combining adjacent blocks that are under half full. So, again, why bother doing an
OPTIMIZE
. - Your question asks about "fixed-length" fields -- that applies only to MyISAM, which has a radically different table structure.
Does the DELETE
take a long time? Is it a burden on the rest of the activity in the server? If so, there is a much better solution than OPTIMIZE
... Partition.
I would consider partitioning on 5-minute intervals. And do a DROP PARTITION
every 5 minutes. It will be a lot less invasive than a big DELETE
. More discussion: http://mysql.rjweb.org/doc.php/partitionmaint
How often do you currently do the DELETE
? Even if you don't go with PARTITIONing
, write a script that continually repeats the DELETE
. This will decrease the impact significantly over any approach using cron
.
Side issues:
Indexing counter
is quite a burden. Each time a counter
is updated, the old index entry needs to be removed and an new entry needs to be added somewhere else.
Why are deleting on date
? You might be bumping the counter one second, then deleting the row the next second.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f201794%2fshould-i-defragment-innodb-table-with-fixed-length-fields%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I would say yes for four(4) major reasons
- Page Boundaries / Index Pages
- Index Layout
- Index Statistics
- Bulk DML
PAGE BOUNDARIES / INDEX PAGES
According to the MySQL Documentation on Limits on InnoDB tables
The maximum row length, except for variable-length columns (VARBINARY, VARCHAR, BLOB and TEXT), is slightly less than half of a page for 4KB, 8KB, 16KB, and 32KB page sizes. For example, the maximum row length for the default innodb_page_size of 16KB is about 8000 bytes. For an InnoDB page size of 64KB, the maximum row length is about 16000 bytes. LONGBLOB and LONGTEXT columns must be less than 4GB, and the total row length, including BLOB and TEXT columns, must be less than 4GB.
Your table uses INT UNSIGNED (4 bytes), DATETIME (8 bytes), 2 SMALLINTs (4 bytes) per row. That's a total of 16 bytes per row. This means you can fit 1000 rows into a single InnoDB page, but there is a very small piece of fragmentation. Using the default innodb_page_size (16K or 16384), there will be 384 bytes of fragmentation with a page. It is most likely used for mapping the data within the one page.
Doing mass INSERTs, DELETEs, and UPDATEs will generate many pages with empty space for whole rows that are marked as unused. This is in addition to the 384 bytes region of the data page.
INDEX LAYOUT
You will generate many index pages
- You have a 6-byte PRIMARY KEY
- Each secondary index carries a copy of the PRIMARY KEY
KEY external_id (external_id),
will be 8 bytes (SMALLINT + PRIMARY KEY)
KEY counter (counter),
will be 8 bytes (SMALLINT + PRIMARY KEY)
KEY date_idx (date)
will be 14 bytes (DATE + PRIMARY KEY)- 36 bytes for indexing a single row
- Indexes are represented as BTREEs, so you are looking at O(n log n) space utilization. If you account for non-leaf page splits, many index pages will be 50% empty (without question).
INDEX STATISTICS
Running INSERTs, DELETEs, and UPDATEs will skew index stats since index cardinalities will frequently change. You need to run ANALYZE TABLE tbl_log;
. Running OPTIMIZE TABLE tbl_log;
will defrag the tables and run ANALYZE TABLE tbl_log;
as the last step (See my post from Feb 27, 2013
: What is the difference between optimize table and analyze table in mysql)
BULK DML
The DELETE query you will be doing by the hour is a bulk operation. Many rows will need a ton of housecleaning to keep up with marking rows deleted.
No, you can't hold 1000 rows per page. There is per-column, per-row, and per-block overheads. You'll be lucky to get 500 rows/block.
– Rick James
Mar 23 '18 at 0:55
DATETIME
is no longer 8 bytes, but only 5 in newer versions.
– Rick James
Mar 23 '18 at 0:57
The PK is 9 bytes, not 6. Hence, all the math about secondary keys is off. Plus there is overhead in secondary key BTrees.
– Rick James
Mar 23 '18 at 0:57
Block splits lead to the BTree being an average of 69% full. This is not bad, and should be ignored.
– Rick James
Mar 23 '18 at 1:00
add a comment |
I would say yes for four(4) major reasons
- Page Boundaries / Index Pages
- Index Layout
- Index Statistics
- Bulk DML
PAGE BOUNDARIES / INDEX PAGES
According to the MySQL Documentation on Limits on InnoDB tables
The maximum row length, except for variable-length columns (VARBINARY, VARCHAR, BLOB and TEXT), is slightly less than half of a page for 4KB, 8KB, 16KB, and 32KB page sizes. For example, the maximum row length for the default innodb_page_size of 16KB is about 8000 bytes. For an InnoDB page size of 64KB, the maximum row length is about 16000 bytes. LONGBLOB and LONGTEXT columns must be less than 4GB, and the total row length, including BLOB and TEXT columns, must be less than 4GB.
Your table uses INT UNSIGNED (4 bytes), DATETIME (8 bytes), 2 SMALLINTs (4 bytes) per row. That's a total of 16 bytes per row. This means you can fit 1000 rows into a single InnoDB page, but there is a very small piece of fragmentation. Using the default innodb_page_size (16K or 16384), there will be 384 bytes of fragmentation with a page. It is most likely used for mapping the data within the one page.
Doing mass INSERTs, DELETEs, and UPDATEs will generate many pages with empty space for whole rows that are marked as unused. This is in addition to the 384 bytes region of the data page.
INDEX LAYOUT
You will generate many index pages
- You have a 6-byte PRIMARY KEY
- Each secondary index carries a copy of the PRIMARY KEY
KEY external_id (external_id),
will be 8 bytes (SMALLINT + PRIMARY KEY)
KEY counter (counter),
will be 8 bytes (SMALLINT + PRIMARY KEY)
KEY date_idx (date)
will be 14 bytes (DATE + PRIMARY KEY)- 36 bytes for indexing a single row
- Indexes are represented as BTREEs, so you are looking at O(n log n) space utilization. If you account for non-leaf page splits, many index pages will be 50% empty (without question).
INDEX STATISTICS
Running INSERTs, DELETEs, and UPDATEs will skew index stats since index cardinalities will frequently change. You need to run ANALYZE TABLE tbl_log;
. Running OPTIMIZE TABLE tbl_log;
will defrag the tables and run ANALYZE TABLE tbl_log;
as the last step (See my post from Feb 27, 2013
: What is the difference between optimize table and analyze table in mysql)
BULK DML
The DELETE query you will be doing by the hour is a bulk operation. Many rows will need a ton of housecleaning to keep up with marking rows deleted.
No, you can't hold 1000 rows per page. There is per-column, per-row, and per-block overheads. You'll be lucky to get 500 rows/block.
– Rick James
Mar 23 '18 at 0:55
DATETIME
is no longer 8 bytes, but only 5 in newer versions.
– Rick James
Mar 23 '18 at 0:57
The PK is 9 bytes, not 6. Hence, all the math about secondary keys is off. Plus there is overhead in secondary key BTrees.
– Rick James
Mar 23 '18 at 0:57
Block splits lead to the BTree being an average of 69% full. This is not bad, and should be ignored.
– Rick James
Mar 23 '18 at 1:00
add a comment |
I would say yes for four(4) major reasons
- Page Boundaries / Index Pages
- Index Layout
- Index Statistics
- Bulk DML
PAGE BOUNDARIES / INDEX PAGES
According to the MySQL Documentation on Limits on InnoDB tables
The maximum row length, except for variable-length columns (VARBINARY, VARCHAR, BLOB and TEXT), is slightly less than half of a page for 4KB, 8KB, 16KB, and 32KB page sizes. For example, the maximum row length for the default innodb_page_size of 16KB is about 8000 bytes. For an InnoDB page size of 64KB, the maximum row length is about 16000 bytes. LONGBLOB and LONGTEXT columns must be less than 4GB, and the total row length, including BLOB and TEXT columns, must be less than 4GB.
Your table uses INT UNSIGNED (4 bytes), DATETIME (8 bytes), 2 SMALLINTs (4 bytes) per row. That's a total of 16 bytes per row. This means you can fit 1000 rows into a single InnoDB page, but there is a very small piece of fragmentation. Using the default innodb_page_size (16K or 16384), there will be 384 bytes of fragmentation with a page. It is most likely used for mapping the data within the one page.
Doing mass INSERTs, DELETEs, and UPDATEs will generate many pages with empty space for whole rows that are marked as unused. This is in addition to the 384 bytes region of the data page.
INDEX LAYOUT
You will generate many index pages
- You have a 6-byte PRIMARY KEY
- Each secondary index carries a copy of the PRIMARY KEY
KEY external_id (external_id),
will be 8 bytes (SMALLINT + PRIMARY KEY)
KEY counter (counter),
will be 8 bytes (SMALLINT + PRIMARY KEY)
KEY date_idx (date)
will be 14 bytes (DATE + PRIMARY KEY)- 36 bytes for indexing a single row
- Indexes are represented as BTREEs, so you are looking at O(n log n) space utilization. If you account for non-leaf page splits, many index pages will be 50% empty (without question).
INDEX STATISTICS
Running INSERTs, DELETEs, and UPDATEs will skew index stats since index cardinalities will frequently change. You need to run ANALYZE TABLE tbl_log;
. Running OPTIMIZE TABLE tbl_log;
will defrag the tables and run ANALYZE TABLE tbl_log;
as the last step (See my post from Feb 27, 2013
: What is the difference between optimize table and analyze table in mysql)
BULK DML
The DELETE query you will be doing by the hour is a bulk operation. Many rows will need a ton of housecleaning to keep up with marking rows deleted.
I would say yes for four(4) major reasons
- Page Boundaries / Index Pages
- Index Layout
- Index Statistics
- Bulk DML
PAGE BOUNDARIES / INDEX PAGES
According to the MySQL Documentation on Limits on InnoDB tables
The maximum row length, except for variable-length columns (VARBINARY, VARCHAR, BLOB and TEXT), is slightly less than half of a page for 4KB, 8KB, 16KB, and 32KB page sizes. For example, the maximum row length for the default innodb_page_size of 16KB is about 8000 bytes. For an InnoDB page size of 64KB, the maximum row length is about 16000 bytes. LONGBLOB and LONGTEXT columns must be less than 4GB, and the total row length, including BLOB and TEXT columns, must be less than 4GB.
Your table uses INT UNSIGNED (4 bytes), DATETIME (8 bytes), 2 SMALLINTs (4 bytes) per row. That's a total of 16 bytes per row. This means you can fit 1000 rows into a single InnoDB page, but there is a very small piece of fragmentation. Using the default innodb_page_size (16K or 16384), there will be 384 bytes of fragmentation with a page. It is most likely used for mapping the data within the one page.
Doing mass INSERTs, DELETEs, and UPDATEs will generate many pages with empty space for whole rows that are marked as unused. This is in addition to the 384 bytes region of the data page.
INDEX LAYOUT
You will generate many index pages
- You have a 6-byte PRIMARY KEY
- Each secondary index carries a copy of the PRIMARY KEY
KEY external_id (external_id),
will be 8 bytes (SMALLINT + PRIMARY KEY)
KEY counter (counter),
will be 8 bytes (SMALLINT + PRIMARY KEY)
KEY date_idx (date)
will be 14 bytes (DATE + PRIMARY KEY)- 36 bytes for indexing a single row
- Indexes are represented as BTREEs, so you are looking at O(n log n) space utilization. If you account for non-leaf page splits, many index pages will be 50% empty (without question).
INDEX STATISTICS
Running INSERTs, DELETEs, and UPDATEs will skew index stats since index cardinalities will frequently change. You need to run ANALYZE TABLE tbl_log;
. Running OPTIMIZE TABLE tbl_log;
will defrag the tables and run ANALYZE TABLE tbl_log;
as the last step (See my post from Feb 27, 2013
: What is the difference between optimize table and analyze table in mysql)
BULK DML
The DELETE query you will be doing by the hour is a bulk operation. Many rows will need a ton of housecleaning to keep up with marking rows deleted.
answered Mar 20 '18 at 16:43
RolandoMySQLDBARolandoMySQLDBA
142k24223379
142k24223379
No, you can't hold 1000 rows per page. There is per-column, per-row, and per-block overheads. You'll be lucky to get 500 rows/block.
– Rick James
Mar 23 '18 at 0:55
DATETIME
is no longer 8 bytes, but only 5 in newer versions.
– Rick James
Mar 23 '18 at 0:57
The PK is 9 bytes, not 6. Hence, all the math about secondary keys is off. Plus there is overhead in secondary key BTrees.
– Rick James
Mar 23 '18 at 0:57
Block splits lead to the BTree being an average of 69% full. This is not bad, and should be ignored.
– Rick James
Mar 23 '18 at 1:00
add a comment |
No, you can't hold 1000 rows per page. There is per-column, per-row, and per-block overheads. You'll be lucky to get 500 rows/block.
– Rick James
Mar 23 '18 at 0:55
DATETIME
is no longer 8 bytes, but only 5 in newer versions.
– Rick James
Mar 23 '18 at 0:57
The PK is 9 bytes, not 6. Hence, all the math about secondary keys is off. Plus there is overhead in secondary key BTrees.
– Rick James
Mar 23 '18 at 0:57
Block splits lead to the BTree being an average of 69% full. This is not bad, and should be ignored.
– Rick James
Mar 23 '18 at 1:00
No, you can't hold 1000 rows per page. There is per-column, per-row, and per-block overheads. You'll be lucky to get 500 rows/block.
– Rick James
Mar 23 '18 at 0:55
No, you can't hold 1000 rows per page. There is per-column, per-row, and per-block overheads. You'll be lucky to get 500 rows/block.
– Rick James
Mar 23 '18 at 0:55
DATETIME
is no longer 8 bytes, but only 5 in newer versions.– Rick James
Mar 23 '18 at 0:57
DATETIME
is no longer 8 bytes, but only 5 in newer versions.– Rick James
Mar 23 '18 at 0:57
The PK is 9 bytes, not 6. Hence, all the math about secondary keys is off. Plus there is overhead in secondary key BTrees.
– Rick James
Mar 23 '18 at 0:57
The PK is 9 bytes, not 6. Hence, all the math about secondary keys is off. Plus there is overhead in secondary key BTrees.
– Rick James
Mar 23 '18 at 0:57
Block splits lead to the BTree being an average of 69% full. This is not bad, and should be ignored.
– Rick James
Mar 23 '18 at 1:00
Block splits lead to the BTree being an average of 69% full. This is not bad, and should be ignored.
– Rick James
Mar 23 '18 at 1:00
add a comment |
I say "no" for various reasons.
- The fragmentation will recur promptly after the
OPTIMIZE
, so why bother. - The fragmentation is not that big a deal. The performance issue is minimal. The "depth" of the BTrees rarely changes due to fragmentation.
- InnoDB tends to get rid of fragmentation by combining adjacent blocks that are under half full. So, again, why bother doing an
OPTIMIZE
. - Your question asks about "fixed-length" fields -- that applies only to MyISAM, which has a radically different table structure.
Does the DELETE
take a long time? Is it a burden on the rest of the activity in the server? If so, there is a much better solution than OPTIMIZE
... Partition.
I would consider partitioning on 5-minute intervals. And do a DROP PARTITION
every 5 minutes. It will be a lot less invasive than a big DELETE
. More discussion: http://mysql.rjweb.org/doc.php/partitionmaint
How often do you currently do the DELETE
? Even if you don't go with PARTITIONing
, write a script that continually repeats the DELETE
. This will decrease the impact significantly over any approach using cron
.
Side issues:
Indexing counter
is quite a burden. Each time a counter
is updated, the old index entry needs to be removed and an new entry needs to be added somewhere else.
Why are deleting on date
? You might be bumping the counter one second, then deleting the row the next second.
add a comment |
I say "no" for various reasons.
- The fragmentation will recur promptly after the
OPTIMIZE
, so why bother. - The fragmentation is not that big a deal. The performance issue is minimal. The "depth" of the BTrees rarely changes due to fragmentation.
- InnoDB tends to get rid of fragmentation by combining adjacent blocks that are under half full. So, again, why bother doing an
OPTIMIZE
. - Your question asks about "fixed-length" fields -- that applies only to MyISAM, which has a radically different table structure.
Does the DELETE
take a long time? Is it a burden on the rest of the activity in the server? If so, there is a much better solution than OPTIMIZE
... Partition.
I would consider partitioning on 5-minute intervals. And do a DROP PARTITION
every 5 minutes. It will be a lot less invasive than a big DELETE
. More discussion: http://mysql.rjweb.org/doc.php/partitionmaint
How often do you currently do the DELETE
? Even if you don't go with PARTITIONing
, write a script that continually repeats the DELETE
. This will decrease the impact significantly over any approach using cron
.
Side issues:
Indexing counter
is quite a burden. Each time a counter
is updated, the old index entry needs to be removed and an new entry needs to be added somewhere else.
Why are deleting on date
? You might be bumping the counter one second, then deleting the row the next second.
add a comment |
I say "no" for various reasons.
- The fragmentation will recur promptly after the
OPTIMIZE
, so why bother. - The fragmentation is not that big a deal. The performance issue is minimal. The "depth" of the BTrees rarely changes due to fragmentation.
- InnoDB tends to get rid of fragmentation by combining adjacent blocks that are under half full. So, again, why bother doing an
OPTIMIZE
. - Your question asks about "fixed-length" fields -- that applies only to MyISAM, which has a radically different table structure.
Does the DELETE
take a long time? Is it a burden on the rest of the activity in the server? If so, there is a much better solution than OPTIMIZE
... Partition.
I would consider partitioning on 5-minute intervals. And do a DROP PARTITION
every 5 minutes. It will be a lot less invasive than a big DELETE
. More discussion: http://mysql.rjweb.org/doc.php/partitionmaint
How often do you currently do the DELETE
? Even if you don't go with PARTITIONing
, write a script that continually repeats the DELETE
. This will decrease the impact significantly over any approach using cron
.
Side issues:
Indexing counter
is quite a burden. Each time a counter
is updated, the old index entry needs to be removed and an new entry needs to be added somewhere else.
Why are deleting on date
? You might be bumping the counter one second, then deleting the row the next second.
I say "no" for various reasons.
- The fragmentation will recur promptly after the
OPTIMIZE
, so why bother. - The fragmentation is not that big a deal. The performance issue is minimal. The "depth" of the BTrees rarely changes due to fragmentation.
- InnoDB tends to get rid of fragmentation by combining adjacent blocks that are under half full. So, again, why bother doing an
OPTIMIZE
. - Your question asks about "fixed-length" fields -- that applies only to MyISAM, which has a radically different table structure.
Does the DELETE
take a long time? Is it a burden on the rest of the activity in the server? If so, there is a much better solution than OPTIMIZE
... Partition.
I would consider partitioning on 5-minute intervals. And do a DROP PARTITION
every 5 minutes. It will be a lot less invasive than a big DELETE
. More discussion: http://mysql.rjweb.org/doc.php/partitionmaint
How often do you currently do the DELETE
? Even if you don't go with PARTITIONing
, write a script that continually repeats the DELETE
. This will decrease the impact significantly over any approach using cron
.
Side issues:
Indexing counter
is quite a burden. Each time a counter
is updated, the old index entry needs to be removed and an new entry needs to be added somewhere else.
Why are deleting on date
? You might be bumping the counter one second, then deleting the row the next second.
answered Mar 23 '18 at 1:16
Rick JamesRick James
42.9k22259
42.9k22259
add a comment |
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f201794%2fshould-i-defragment-innodb-table-with-fixed-length-fields%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown