Ich habe eine einzige Datenbank mit ungefähr 100 Tabellen, um verschiedene Arten von Informationen zu speichern.
Die wichtigste Tabelle ist unsere Auftragstabelle, in der Kundenbestellungen gespeichert werden und die derzeit über 100000 Datensätze umfasst und wächst.
Diese Tabelle ist die am häufigsten abgefragte Tabelle in unserer Datenbank für verschiedene Teile von Informationen, die von Echtzeit-Auftrags-Dashboards, Statistiken, Analysen usw. benötigt werden.
Ich überwache die Datenbank regelmäßig und habe langsame Abfragen in der Datenbank aktiviert, um Probleme zu verfolgen.
Ich benutze Skripte wie mysqltuner, um täglich Abfragen auszuspucken.
Ich benutze auch mysqlsla, um Informationen über die 10 langsamsten Abfragen in unserer Datenbank zu sammeln.
sample stat
Count : 11.48k (30.66%)
Time : 19.623758 s total, 1.709 ms avg, 239 µs to 2.475017 s max (18.64%)
95% of Time : 5.246833 s total, 481 µs avg, 239 µs to 1.095 ms max
Lock Time (s) : 14.460071 s total, 1.259 ms avg, 53 µs to 2.462555 s max (41.38%)
95% of Lock : 806.43 ms total, 74 µs avg, 53 µs to 137 µs max
Rows sent : 1 avg, 0 to 9 max (0.99%)
Rows examined : 6 avg, 1 to 28 max (0.15%)
Die meisten der am langsamsten abgefragten betreffen die oben genannte Auftragstabelle. Ich verwende MyISAM als Speicher-Engine, sodass mögliche Probleme auftreten können:
- Tischsperre
- Indizierungsprobleme
Wie könnte ich diese Statistiken verbessern? Ich habe eine Indizierung für diese Tabellen eingerichtet und sie ständig optimiert, um die Leseabfragen zu verbessern.
Tabellenschema
`orderid` int(11) NOT NULL AUTO_INCREMENT,
`cityid` tinyint(3) unsigned NOT NULL DEFAULT '1',
`model_type` tinyint(1) unsigned DEFAULT '1',
`userid` int(11) DEFAULT NULL,
`usertype` char(1) DEFAULT NULL,
`time` time DEFAULT NULL,
`ordercode` char(8) DEFAULT NULL,
`restid` smallint(3) unsigned NOT NULL,
`areaid` smallint(3) unsigned DEFAULT NULL,
`restname` varchar(50) DEFAULT NULL,
`date` date NOT NULL,
`del_time` time NOT NULL,
`status` tinyint(3) unsigned NOT NULL,
`amount` float NOT NULL,
`deliverycharge` smallint(4) unsigned DEFAULT '0',
`tax` float NOT NULL,
`total` float NOT NULL,
`extras` varchar(255) DEFAULT NULL,
`requests` varchar(255) DEFAULT NULL,
`discount` float DEFAULT NULL,
`rdiscount` float DEFAULT NULL,
`reason` varchar(255) DEFAULT NULL,
`rest_order` tinyint(1) unsigned DEFAULT NULL,
`admin_user` varchar(25) DEFAULT NULL,
`mode` char(1) NOT NULL,
`priority_order` tinyint(1) unsigned DEFAULT '0',
`payment_mode` tinyint(1) unsigned DEFAULT '0',
`km` tinyint(3) unsigned DEFAULT NULL,
`order_type` tinyint(1) NOT NULL DEFAULT '1',
`coupon_discount` smallint(3) DEFAULT '0',
`pickup_time` time NOT NULL,
PRIMARY KEY (`orderid`),
KEY `cityid` (`cityid`),
KEY `date_3` (`date`,`status`,`mode`),
KEY `orderid` (`orderid`),
KEY `time` (`time`),
KEY `userid` (`userid`,`usertype`),
KEY `restid` (`restid`,`date`,`status`)
langsame Protokollabfrage
SELECT `a`.`orderid`, `a`.`date`, `a`.`status`, `a`.`restname`, `a`.`admin_user`, `a`.`model_type`, `b`.`name` as cityname
FROM `tk_order_queue` AS a
INNER JOIN `tk_cities` AS b ON `a`.`cityid` = `b`.`id`
WHERE `a`.`date` = '2012-06-30'
AND `a`.`status` = 0
AND `a`.`mode` = 1
ORDER BY `a`.`orderid` desc;
SHOW CREATE TABLE orders\G
und posten Sie das in der FrageAntworten:
Sie müssen die WHERE-Klauseln sowie die Anweisungen GROUP BY und ORDER BY aller Ihrer Abfragen vergleichen, um sicherzustellen, dass Ihre aktuellen Indizes sie in ihren EXPLAIN-Plänen unterstützen können.
Gestern habe ich diese Frage beantwortet: InnoDB vs MyISAM mit vielen Indizes
In dieser Frage schlug ich vor, etwas an der MyISAM-Tabelle zu tun, das Sie auch tun können
Dadurch werden alle VARCHARs als CHARs behandelt. Jede Reihe hat genau die gleiche Länge. Dadurch wird der Speicherplatz um 80% bis 100% erhöht. Ihre Tabelle wird auf die maximale Größe für das Zeilenlayout multipliziert mit der Anzahl der Zeilen aufgebläht. Ihr Tisch kann doppelt oder dreifach groß sein.
Wo ist der Nutzen? Ihre MyISAM-Tabelle wird dann zwischen 20% und 30% schneller gelesen / geschrieben, ohne dass etwas anderes geändert wird.
Das habe ich auf den Seiten 72, 73 von MySQL Database Design and Tuning gelernt .
Ich habe darüber in der Vergangenheit geschrieben:
quelle