Tabla MySQL con 100,000 registros consultados a menudo

11

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:

  1. Mesa de bloqueo
  2. 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;
Sheldon
fuente
Por favor, ejecute SHOW CREATE TABLE orders\Gy después de que en la pregunta
RolandoMySQLDBA
2
¿Lo estoy leyendo incorrectamente o el tiempo promedio de consulta es de 1.7 ms? ¿Por qué demonios buscarías acelerar eso?
Philᵀᴹ
Estoy un poco confundido sobre por qué aparece eso en los registros de consultas lentas.
sheldon
@RolandoMySQLDBA He adjuntado el esquema
sheldon
1
El hecho de que tenga índices en la tabla no significa que sean los índices correctos para sus consultas. ¿Podría publicar algunos ejemplos de consultas lentas y su salida EXPLAIN? Además, ¿con qué frecuencia se actualiza la tabla de pedidos?
bobwienholt

Respuestas:

8

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

ALTER TABLE orders ROW_FORMAT=Fixed;

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:

RolandoMySQLDBA
fuente
Gracias por la explicación detallada, sí, los índices agregados a la tabla se basan en las consultas utilizadas para las selecciones, agrupar y ordenar por declaraciones utilizadas en nuestro sistema. He estado monitoreando las consultas sin registros de índices y actualizando las tablas en consecuencia.
sheldon