InnoDB lagrar "breda" tabeller på ett annat sätt. Istället för att ha alla kolumner tillsammans i en enda sträng (plus overhead, såsom längder, etc.), gör den följande:
- Om summan av alla kolumner för en given rad överstiger cirka 8KB, kommer en del av data att flyttas till ett annat ("off-record") lagringsområde.
- Vilka kolumner som flyttas utanför posten beror på storleken på kolumnerna osv.
- Detaljen beror på
ROW_FORMAT
valt. - "Off-record" är ett annat 16KB block (eller block).
- Senare, när du gör
SELECT *
(eller åtminstone hämtar off-record-kolumn(erna)), måste den göra en annan diskhämtning.
Vad ska man göra?
- Tänk om att ha så många kolumner.
- Tänk på "vertikal partitionering", där du har en annan tabell som innehåller vald
TEXT
kolumner. Föreslå att du väljer grupper av kolumner baserat på åtkomstmönster i din app. - För kolumner som vanligtvis är ganska långa, överväg att komprimera dem i klienten och lagra dem i en
BLOB
istället för enTEXT
. De flesta "texter" krymper 3:1. Blobbar skickas off-record på samma sätt som texter, men dessa komprimerade blobbar skulle vara mindre, och därmed mindre sannolikt att spilla. - Gör mer bearbetning i SQL -- för att undvika att returnera alla rader, eller för att undvika att returnera hela texten, etc. När du blint skyfflar massor av text till en klient blir nätverket och klienten en viktig faktor för den tid som förflutit, inte bara
SELECT
, sig själv.