Permalänk

Indexera timestamp i MySQL

Har en MySQL-tabell som agerar "logg-tabell" och som på sikt skulle kunna få några miljoner rader. Jag vill kunna ta ut endast de rader som är från de senaste 10 dagarna. Anropet ser lite förenklat ut enligt nedan:

SELECT * FROM log_activity WHERE DATE(log_create) >= DATE(NOW()) - INTERVAL 10 DAY

Jag har satt index på log_create som är en timestamp, men ändå får jag en full table scan vilket gör att anropet tar några sekunder vid stor tabell, trots att resultatet kanske bara blir några få rader. Gör jag en EXPLAIN SELECT så verkar det dessutom som att mitt index på log_create inte ens används.

Kan jag göra på något annat sätt för att få snabbare resultat vid detta anrop?

Permalänk
Medlem
Skrivet av Sir.Persson:

Jag har satt index på log_create som är en timestamp, men ändå får jag en full table scan vilket gör att anropet tar några sekunder vid stor tabell, trots att resultatet kanske bara blir några få rader. Gör jag en EXPLAIN SELECT så verkar det dessutom som att mitt index på log_create inte ens används.
Kan jag göra på något annat sätt för att få snabbare resultat vid detta anrop?

Då du har et funktionsanrop i din where så kan MySQL inte använda index eftersom den måste kalla funktionen DATE för varje rad i din tabell för att sen kunna jämföra.
Antingen så skapar du en ny column med datan förpopulerad med DATE(log_create) vid INSERT/UPDATE eller så använder du den nya "Functional Indexes" enligt exempel : https://dasini.net/blog/2019/03/14/mysql-functional-indexes/

Permalänk
Vila i frid
Skrivet av Sir.Persson:

Kan jag göra på något annat sätt för att få snabbare resultat vid detta anrop?

Har du provat "between" t.ex.
where log_create BETWEEN @Date1 AND @Date2

Där definitionen av @Date1 och @Date2 sker innan SELECT - spar en himla massa cpu om CAST slipper vara med i loopen.

Mitt exempel tog jag från egen mssql-kod, kan behöva anpassas för mysql.

Permalänk
Avstängd
Skrivet av hasenfrasen:

Har du provat "between" t.ex.
where log_create BETWEEN @Date1 AND @Date2

Där definitionen av @Date1 och @Date2 sker innan SELECT - spar en himla massa cpu om CAST slipper vara med i loopen.

Mitt exempel tog jag från egen mssql-kod, kan behöva anpassas för mysql.

Jo något sånt hade jag nog också försökt mig på, ett problem som antyds är att log_create inte är i formatet DATE, men det skulle ju kunna vara ett tidsformat ändå, bara inte just DATE, och då borde man kunna jämföra mot ett DATE ändå. Eller i T-SQL i alla fall, har inte koll på MySQL.

Men typ:

DECLARE @tenDaysAgo DATETIME = DATEADD(day, -10, GETDATE()) SELECT * FROM log_activity WHERE log_create >= @tenDaysAgo

Permalänk
Vila i frid
Permalänk
Medlem

Jag använder mig själv av date between '' and '' i min kod till sql.
Och date_modify() i php-koden som används till mysql för att få fram det som inte är dagens datum.

tex:

$date=date_create();
date_modify($date,"-10days");
echo date_format($date,"Y-m-d");

Visa signatur

I5 9600k@stock / Cooler Master Evo 212 / Gigabyte Z390 Gaming X / Corsair Vengeance LPX 16GB DDR4 3000MHz / MSI RTX2070 Gaming Z / EVGA 550 BQ / Asus VG27BQ 27" 165Hz

Ryzen 5 5600x@stock / Asus Rog Strix X570-E Gaming / Corsair Vengeance RGB Pro 16GB 3600MHz CL18 / MSI RTX3070 Suprim X / BeQuiet Pure Power 11 600W / Asus VG278Q 27" 144Hz