I am trying to compare the myisam and innodb write/read performance, but I am suprised that the myisam's read is much more slower than innodb while its write is much more faster, this is totally opposite compared to what I have learned.
The mysql version is 5.7.18-0ubuntu0.16.04.1.
here are my two tables:
mysql> show create table inno_1;
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| inno_1 | CREATE TABLE `inno_1` (
`id` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
mysql> show create table isam_1;
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| isam_1 | CREATE TABLE `isam_1` (
`id` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
I tried to write twice 50000 rows to the two tables
[2017-08-07 15:57:12] [0.86ms] INSERT INTO `inno_1` (`id`,`name`,`created_at`,`updated_at`) VALUES ('11e77b46-0576-5c30-8e53-1c1b0d1700f9','xxx','2017-08-07 15:57:12','2017-08-07 15:57:12')
[1 rows affected or returned ]
insert time : 1m23.905679587s
[2017-08-07 15:55:49] [0.11ms] INSERT INTO `isam_1` (`id`,`name`,`created_at`,`updated_at`) VALUES ('11e77b45-d416-79b0-8804-1c1b0d1700f9','xxx','2017-08-07 15:55:49','2017-08-07 15:55:49')
[1 rows affected or returned ]
insert time : 5.500709602s
while for the read:
[2017-08-07 15:57:17] [20.95ms] SELECT * FROM `inno_1` ORDER BY id asc LIMIT 1000 OFFSET 100000
[0 rows affected or returned ]
select time : 2.076151355s
[2017-08-07 15:56:24] [353.06ms] SELECT * FROM `isam_1` ORDER BY id asc LIMIT 1000 OFFSET 100000
[0 rows affected or returned ]
select time : 32.030940358s
I don't understand why it is so different from the official advice, if I changed the id to int, the myisam's read gets improved a lot.
mysql> show create table inno;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| inno | CREATE TABLE `inno` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=50001 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> show create table isam;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| isam | CREATE TABLE `isam` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=50001 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
myisam
[2017-08-07 16:08:37] [0.09ms] INSERT INTO `isam` (`name`,`created_at`,`updated_at`) VALUES ('xxx','2017-08-07 16:08:37','2017-08-07 16:08:37')
[1 rows affected or returned ]
insert time : 4.745437221s
[2017-08-07 16:08:41] [12.55ms] SELECT * FROM `isam` ORDER BY id asc LIMIT 1000 OFFSET 50000
[0 rows affected or returned ]
select time : 1.105638295s
innodb:
[2017-08-07 16:09:26] [0.87ms] INSERT INTO `inno` (`name`,`created_at`,`updated_at`) VALUES ('xxx','2017-08-07 16:09:26','2017-08-07 16:09:26')
[1 rows affected or returned ]
insert time : 1m28.577975501s
[2017-08-07 16:09:30] [9.58ms] SELECT * FROM `inno` ORDER BY id asc LIMIT 1000 OFFSET 50000
[0 rows affected or returned ]
select time : 739.580336ms
could anyone explain?
UPDATE:
I use 10 threads for writing first, then 1 thread for reading.
isam_1
ORDER BY id asc LIMIT 1000 OFFSET 147000", a query order by string id, takes too much time, while innodb is much faster. – seaguestfixed
row format for MyISAM.) – SolarflareCount
is a very special case. MyISAM can just take the current number from statistics for it. InnoDB cannot do that, because that value isn't stored for InnoDB tables. That is because of the way transactions work - the count will e.g. reflect the count for the current transaction, and there is currently not a single place where is can be stored. Maybe some day someone will add such a feature, probably as a by-product of some other optimization, as for just "count" it is probably not worth the required changes. If you need it, you can create your own statistics table using e.g. a trigger. – Solarflare