The old cliche SIZE MATTERS
applies here without a doubt.
Smaller keys would load into a table faster that with biggers (This becomes even more evident with InnoDB). The bigger the columns in the index, the fewer the keys would be residing in BTREE pages. Thus, you get taller BTREE trees. Even a BTREE height of 3 or more, which is bad for a small table, would be the result of having large columns. The same would apply to the name (up to 150 characters) and category (up to 100 characters) fields. Making all columns CHAR instead of VARCHAR would increase SELECT performance, but the significant increase of diskspace + BTREE node management would throw SELECT performance under the bus as the table grows.
Looking at all of your keys I can see this table being extermely lopsided in index size verses table size.
Please run this query
SELECT data_lenth,index_length
FROM information_schema.tables
WHERE table_name = 'acl_action';
You will see the combined sum of all index pages being as large or larger than the table. From a physical standpoint, the file acl_actions.MYI will be bigger that acl_actions.MYD.
Here is where random I/O would come into play: Notice your index idx_aclaction_id_del
Notice that you have it defined as
KEY `idx_aclaction_id_del` (`id`,`deleted`),
If you ever decide to query for deleted records, you will get an full index scan because of the order of trhe columns in this index.
KEY `idx_aclaction_del_id` (`deleted`,`id`),
That way all deleted keys are grouped together. Likewise, all non-deleted rows are grouped together.
Try altering the table design like this
CREATE TABLE `acl_actions` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`guid` char(36) NOT NULL,
`date_entered` datetime NOT NULL,
`name` varchar(150) default NULL,
........
`category` varchar(100) default NULL,
`deleted` tinyint(1) default '0',
PRIMARY KEY (`id`),
UNQIUE KEY (`guid`),
KEY `idx_aclaction_id_del` (`deleted`,`id`),
KEY `idx_category_name` (`category`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
You should run the following query
SELECT name,categrory FROM acl_actions PROCEDURE ANALYSE();
This will recommend the correct sizes for those columns with the given dataset.
Best Answer
PRIMARY KEY (OrgID, MachID, Date)
would be good for that query. But, aPRIMARY KEY
is necessarily "unique"; is that combination unique? If not unique, then make it a plainINDEX
and have something else as thePRIMARY KEY
.If we are talking about millions of rows per day, then Summary tables would be worth doing.
If it is usually "yesterday", then consider:
Or, more generically, (where you insert the days ago for '?'):
More
Insuring sequential -- not that important. With that 3-part PK, you will be inserting sequentially in several spots, namely each combination of
OrgID
andMachID
.Insert
do need to update secondary keys, but this is usually not a big deal. (To get really technical, see "InnoDB's change buffering".)If you are going to be inserting more than 100 rows per second, then I recommend gathering them up and batch inserting. Also, see
innodb_flush_log_at_trx_commit = 2
.