Topic: "freeing items" stabdo INSERT ir UPDATE [innoDB]
Sveiki,
kuris laikas naudoju innoDB, tačiau pastebėjau kad joje yra lėtos update ir insert užklausos. Paėmiau profilį:
mysql> show profile for query 4;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000083 |
| checking permissions | 0.000009 |
| Opening tables | 0.000018 |
| System lock | 0.000004 |
| Table lock | 0.000005 |
| init | 0.000061 |
| Updating | 0.000094 |
| end | 0.000008 |
| query end | 0.000003 |
| freeing items | 0.065511 | <<-------
| logging slow query | 0.000011 |
| cleaning up | 0.000004 |
+----------------------+----------+
12 rows in set (0.00 sec)
Pati lentelė:
CREATE TABLE `buildings` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`tid` int(10) unsigned NOT NULL,
`damage` tinyint(3) unsigned NOT NULL DEFAULT '100',
`guest` int(11) NOT NULL DEFAULT '0',
`cost` smallint(5) unsigned NOT NULL,
`builded` int(10) unsigned NOT NULL,
`on` tinyint(1) NOT NULL DEFAULT '1',
`lastTime` int(10) unsigned NOT NULL,
`x` int(11) NOT NULL,
`y` int(11) NOT NULL,
`size` tinyint(1) unsigned NOT NULL,
`static` tinyint(1) NOT NULL DEFAULT '0',
`use` tinyint(1) NOT NULL DEFAULT '1',
`type` enum('P','K','A','L') NOT NULL,
`pasitenkinimas` float unsigned NOT NULL DEFAULT '0',
`connected` tinyint(1) NOT NULL DEFAULT '0',
`hasWorkers` tinyint(1) NOT NULL DEFAULT '0',
`queue` smallint(5) unsigned NOT NULL DEFAULT '0',
`revenue` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=497 DEFAULT CHARSET=latin1
Ji susieta per foregin keys su:
CREATE TABLE `zones` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`x` int(11) NOT NULL,
`y` int(11) NOT NULL,
`block` int(10) unsigned NOT NULL,
`pid` int(10) unsigned DEFAULT NULL,
`building` int(10) unsigned DEFAULT NULL,
`private` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `coo` (`block`,`x`,`y`) USING BTREE,
KEY `pid` (`pid`),
KEY `building` (`building`),
KEY `block` (`block`),
CONSTRAINT `buildingas` FOREIGN KEY (`building`) REFERENCES `buildings` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `parkas` FOREIGN KEY (`pid`) REFERENCES `parks` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=10435 DEFAULT CHARSET=latin1
Bet kadangi tik per building.id, kuris niekada nesikeičia, tačiau pats įrašas gali būti ištrintas.
Visą reikalą stabdo tik tas free items. šitoje lentelėje yra ~1500 įrašų. Kai vykdomos update užklausos, matau kaip HDD lemputė mirkčioja. šita reiškmė nesikeičia išjungus arba įjungus kešą. Produkcinis serveris bus žymiai spartesnis (nes turės 4 SSD RAID masyvą) negu darbinis laptopas, tačiau turės atlaikyti bent 4 milijonus įrašų, ir ~20.000 update per sekundę vien tik šioje lentelėje.
Taigi gal galima kažką pamodifikuoti, kad optimizuoti šitą vietą. Turiu visišką laisvę keisti my.cnf nustatymus. Būtų gerai kad update užklausos būtų įvykdomos per trumpiau nei 1 ms (dabar yra ~65ms kurias užima vien tik tas freeing items);