Tabella MySQL con 100.000 record interrogati spesso


11

Ho un unico database di circa 100 tabelle per memorizzare vari tipi di informazioni.

La tabella più importante è la nostra tabella degli ordini che viene utilizzata per archiviare gli ordini dei clienti e conta oltre 100000 record al momento e in crescita.

Questa tabella è la tabella più richiesta nel nostro database, per varie parti di informazioni necessarie da dashboard di ordini in tempo reale, statistiche, analisi, ecc.

Controllo regolarmente il database e ho abilitato le query lente sul database per tenere traccia dei problemi.

Uso script come mysqltuner per sputare query su base giornaliera.

Uso anche mysqlsla per raccogliere informazioni sulle prime 10 query più lente nel nostro database.

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 maggior parte delle query più lente riguarda la tabella degli ordini sopra menzionata. Uso MyISAM come motore di archiviazione, quindi i possibili problemi potrebbero essere:

  1. Blocco della tabella
  2. Problemi di indicizzazione

Come posso migliorare queste statistiche, ho predisposto l'indicizzazione per queste tabelle e ho continuato a modificarle per migliorare le query di lettura.

Schema della tabella

`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`)

query di registro lento

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;

Si prega di eseguire SHOW CREATE TABLE orders\Ge pubblicare quello nella domanda
RolandoMySQLDBA

2
Lo sto leggendo in modo errato o il tempo di query medio è di 1,7 ms? Perché mai dovresti cercare di accelerarlo?
Philᵀᴹ

Sono un po 'confuso sul perché appare nei registri delle query lente.
sheldon,

@RolandoMySQLDBA ho allegato lo schema
sheldon,

1
Solo perché hai indici nella tabella non significa che siano gli indici giusti per le tue query. Potresti pubblicare alcuni esempi di query lente e il loro output EXPLAIN? Inoltre, con che frequenza viene aggiornata la tabella degli ordini?
bobwienholt,

Risposte:


8

Dovrai confrontare le clausole WHERE e le istruzioni GROUP BY e ORDER BY di tutte le tue query per assicurarti che gli indici attuali possano supportarli nei loro piani EXPLAIN.

Ieri ho risposto a questa domanda: InnoDB vs MyISAM con molti indici

In quella domanda ho suggerito di fare qualcosa alla tabella MyISAM che puoi fare anche tu

ALTER TABLE orders ROW_FORMAT=Fixed;

Questo tratterà tutti i VARCHAR come CHAR. Ogni riga avrà la stessa identica lunghezza. Ciò aumenterà lo spazio su disco dell'80% -100%. La tabella si gonfia fino alla dimensione massima per il layout della riga moltiplicata per il numero di righe. La tua tabella potrebbe raddoppiare o triplicare le dimensioni.

Dov'è il vantaggio? La tua tabella MyISAM verrà quindi letta / scritta in qualsiasi punto dal 20% al 30% più veloce senza cambiare nient'altro.

L'ho imparato dalle pagine 72,73 di MySQL Database Design and Tuning .

Ho scritto su questo in passato:


Grazie per la spiegazione dei dettagli, sì, gli indici aggiunti alla tabella si basano sulle query utilizzate per le istruzioni select, group by e order by utilizzate nel nostro sistema. Ho monitorato le query senza i registri degli indici e aggiornato le tabelle di conseguenza.
sheldon,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.