(Diese Antwort richtet sich an das Schema und SELECT.)
Da Sie mit Millionen von Zeilen rechnen, möchte ich zunächst auf einige Verbesserungen des Schemas hinweisen.
-
FLOAT(m,n)
ist normalerweise das 'Falsche', weil es zu zwei Rundungen führt. Verwenden Sie entweder einfachFLOAT
(was für Metriken wie Spannung "richtig" erscheint) oder verwenden SieDECIMAL(m,n)
.FLOAT
ist 4 Bytes; in den angegebenen FällenDECIMAL
wären 3 oder 4 Bytes. -
Wenn Sie beide
INDEX(a)
haben undINDEX(a,b)
, ersteres ist unnötig, da letzteres solche abdecken kann. Sie haben 3 unnötige SCHLÜSSEL. Dies verlangsamtINSERTs
. -
INT(3)
-- Sagen Sie eine "3-stellige Zahl"? Ziehen Sie in diesem FallTINYINT UNSIGNED
in Betracht (Werte 0..255) für 1 Byte stattINT
für 4 Byte. Dies spart viele MB Speicherplatz und damit Geschwindigkeit. (Siehe auchSMALLINT
, usw. undSIGNED
oderUNSIGNED
.) -
Wenn
filename
wiederholt wird, möchten Sie es vielleicht "normalisieren". Dies würde viele MB einsparen. -
Verwenden Sie
NOT NULL
es sei denn, Sie brauchenNULL
für etwas. -
AUTO_INCREMENT=690892041
impliziert, dass Sie mitid
ungefähr 1/3 des Weges zur Katastrophe zurückgelegt haben , die bei etwa 2 Milliarden liegen wird. Verwenden Sieid
für alles? Das Entfernen der Spalte würde das Problem vermeiden; und ändern Sie denUNIQUE KEY
zuPRIMARY KEY
. (Falls Sieid
benötigen , lass uns weiter reden.) -
ENGINE=MyISAM
-- Der Wechsel hat einige Auswirkungen, sowohl günstige als auch ungünstige. Der Tisch würde 2-3 mal so groß werden. Die 'richtige' Wahl desPRIMARY KEY
würde dies weiter beschleunigenSELECT
bedeutend. (Und kann andereSELECTs
verlangsamen oder auch nicht .)
Ein Hinweis zum SELECT
:Seit string
und unit_num
sind Konstanten in der Abfrage, die letzten beiden Felder von ORDER BY timestamp asc, string asc, unit_num asc
sind unnötig. Wenn sie aus Gründen relevant sind, die im SELECT
nicht ersichtlich sind , dann ist mein Rat möglicherweise unvollständig.
Dies
WHERE filename = 'foobar'
AND unit_num='40'
AND string='2'
AND timestamp >= ...
wird optimal von INDEX(filename, unit_name, string, timestamp)
gehandhabt . Die Reihenfolge der Spalten ist außer nicht wichtig diesen timestamp
muss letzter sein . Neuanordnung des aktuellen UNIQUE
Schlüssel geben Sie Ihnen den optimalen Index. (Inzwischen ist keiner der Indizes sehr gut für dieses SELECT
.) Es zum PRIMARY KEY
machen und die Tabelle InnoDB würde es noch schneller machen.
Partitionieren? Kein Vorteil. Nicht für Leistung; nicht für alles andere, was Sie erwähnt haben. Eine übliche Verwendung für die Partitionierung ist das Löschen von „alten“. Wenn Sie dies beabsichtigen, lassen Sie uns weiter sprechen.
Bei großen Tabellen schaut man sich am besten alle wichtigen SELECTs
an gleichzeitig, damit wir nicht einen beschleunigen, während wir die Geschwindigkeit anderer zerstören. Es kann Es stellt sich sogar heraus, dass die Partitionierung bei dieser Art von Kompromiss hilft.