Tengo una base de datos única de aproximadamente 100 tablas para almacenar varios tipos de información.
La tabla más importante es nuestra tabla de pedidos que se utiliza para almacenar pedidos de clientes y tiene más de 100000 registros a partir de ahora y en crecimiento.
Esta tabla es la tabla más consultada en nuestra base de datos, para varias partes de la información necesaria desde paneles de pedidos en tiempo real, estadísticas, análisis, etc.
Superviso la base de datos de forma regular y tengo consultas lentas habilitadas en la base de datos para rastrear problemas.
Utilizo scripts como mysqltuner para escupir consultas diariamente.
También uso mysqlsla para recopilar información sobre las 10 consultas más lentas de nuestra base de datos.
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%)
La mayoría de las consultas más lentas involucran la tabla de pedidos mencionada anteriormente. Uso MyISAM como mi motor de almacenamiento, por lo que los posibles problemas podrían ser:
- Mesa de bloqueo
- Problemas de indexación
¿Cómo podría mejorar estas estadísticas? Tengo una indexación para estas tablas y las he ajustado para mejorar las consultas de lectura.
Esquema de la tabla
`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`)
consulta de registro lenta
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
y después de que en la preguntaRespuestas:
Tendrá que comparar las cláusulas WHERE y las declaraciones GROUP BY y ORDER BY de todas sus consultas para asegurarse de que sus índices actuales puedan admitirlas en sus planes EXPLAIN.
Ayer, respondí esta pregunta: InnoDB vs MyISAM con muchos índices
En esa pregunta, sugerí hacer algo en la tabla MyISAM que también puedes hacer
Esto tratará a todos los VARCHAR como CHAR. Cada fila tendrá exactamente la misma longitud. Esto aumentará el espacio en disco 80% -100%. Su tabla se hinchará al tamaño máximo para el diseño de fila multiplicado por el número de filas. Su mesa puede duplicar o triplicar su tamaño.
¿Dónde está el beneficio? Su tabla MyISAM se leerá / escribirá desde 20% - 30% más rápido sin cambiar nada más.
Lo aprendí de las páginas 72,73 de MySQL Database Design and Tuning .
He escrito sobre esto en el pasado:
fuente