(Detta svar är riktat till schemat och SELECT.)
Eftersom du förutser miljontals rader vill jag först peka på några förbättringar av schemat.
-
FLOAT(m,n)
är vanligtvis "fel" sak att göra eftersom det leder till två avrundningar. Använd antingen vanligFLOAT
(vilket verkar "rätt" för mätningar som spänning) eller användDECIMAL(m,n)
.FLOAT
är 4 byte; i de angivna fallenDECIMAL
skulle vara 3 eller 4 byte. -
När du har både
INDEX(a)
ochINDEX(a,b)
, det förra är onödigt eftersom det senare kan täcka för sådant. Du har 3 onödiga NYCKLAR. Detta saktar nerINSERTs
. -
INT(3)
-- Säger du ett "3-siffrigt nummer"? Om så är fallet, övervägTINYINT UNSIGNED
(värden 0..255) för 1 byte istället förINT
för 4 byte. Detta kommer att spara många MB diskutrymme, därav hastighet. (Se ävenSMALLINT
, etc, ochSIGNED
ellerUNSIGNED
.) -
Om
filename
upprepas mycket, du kanske vill "normalisera" det. Detta skulle spara många MB. -
Använd
NOT NULL
om du inte behöverNULL
för något. -
AUTO_INCREMENT=690892041
innebär att du är ungefär 1/3 av vägen till katastrof medid
, som kommer att toppa på cirka 2 miljarder. Använder duid
för allt? Att bli av med kolumnen skulle undvika problemet; och ändraUNIQUE KEY
tillPRIMARY KEY
. (Om du behöverid
, låt oss prata vidare.) -
ENGINE=MyISAM
-- Byte har vissa konsekvenser, både gynnsamma och ogynnsamma. Bordet skulle bli 2-3 gånger så stort. Det "rätta" valet avPRIMARY KEY
skulle påskynda det här ytterligareSELECT
väsentligt. (Och kan eller inte kan sakta ner andraSELECTs
.)
En anteckning om SELECT
:Sedan string
och unit_num
är konstanter i frågan, de två sista fälten i ORDER BY timestamp asc, string asc, unit_num asc
är onödiga. Om de är relevanta av skäl som inte framgår av SELECT
, då kan mitt råd vara ofullständigt.
Detta
WHERE filename = 'foobar'
AND unit_num='40'
AND string='2'
AND timestamp >= ...
hanteras optimalt av INDEX(filename, unit_name, string, timestamp)
. Ordningen på kolumnerna är inte viktig förutom den timestamp
måste vara sista . Ordna om den nuvarande UNIQUE
nyckel ger du dig det optimala indexet. (Under tiden är inget av indexen särskilt bra för denna SELECT
.) Gör den till PRIMARY KEY
och tabellen InnoDB skulle göra det ännu snabbare.
Partitionering? Ingen fördel. Inte för prestanda; inte för något annat du har nämnt. En vanlig användning för partitionering är att rensa "gammalt". Om du tänker göra det, låt oss prata vidare.
I stora tabeller är det bäst att titta på alla viktiga SELECTs
samtidigt så att vi inte sätter fart på en samtidigt som vi raserar hastigheten på andra. Det kan till och med visa sig att partitionering hjälper till i denna typ av avvägning.