2015-06-10 20 views
9

Ho una tabella DB MySQL con più campi di tipo data. Devo fare diverse query SELECT su questo tavolo ma non sono sicuro di quale sia il modo migliore per trovare i record dello stesso mese.Query SELEZIONA efficiente per trovare i record entro un mese

so di poter effettuare le seguenti operazioni:

SELECT * 
    FROM table 
WHERE MONTH(somedate) = 5 
    AND YEAR(somedate) = 2015 

Ma Continuo a leggere che non è efficiente e che avrei dovuto andare con l'utilizzo di date effettive, cioè

SELECT * 
    FROM table 
WHERE somedate BETWEEN '2015-05-01' AND '2015-05-31' 

Tuttavia, tutto quello che ho sarebbe il mese e l'anno come variabili provenienti da PHP. Come faccio a calcolare facilmente e velocemente l'ultimo giorno del mese se vado con la seconda opzione?

+0

Sto trovando "tra" per essere più lento di "mese/anno", e "mi piace", sul mio db. Mese/anno = 'Visualizza le righe da 0 a 29 (77 totali, Query ha impiegato 0,0825 sec)'. Tra = = Visualizzazione delle righe 0 - 29 (77 totali, Query ha richiesto 0,1059 sec) '. Mi piace = 'Mostra le righe 0 - 29 (77 totali, Query ha impiegato 0.0815 sec)'. Questo è su una tabella di fila 7k. Questo thread punta nell'altra direzione però. http://dba.stackexchange.com/questions/96245/mysql-date-field-filter-by-like-vs-month – chris85

+0

MySQL può fare un uso efficace di un indice con la colonna principale di 'somedate'. Se non hai un indice del genere, puoi crearne uno, ad es. 'CREATE INDEX ON table (somedate)'. Finché la query restituisce meno del 10% delle righe nella tabella, l'indice renderà la query molto più veloce. Con le funzioni racchiuse nella colonna somedate, MySQL deve valutare quelle funzioni su ogni riga della tabella. – spencer7593

+0

Utilizzare 'EXPLAIN' per vedere il piano di esecuzione. Per i confronti delle prestazioni, assicurarsi che i risultati della query non vengano restituiti dalla cache della query. Ci sono diversi modi per farlo, ad esempio, hit "SQL_NO_CACHE", includere la variabile definita dall'utente nella query, disabilitare la cache delle query, ecc. (In realtà i nostri server MySQL sono configurati per memorizzare solo * query * che includono l'hint 'SQL_CACHE' , quindi controlliamo quali query possono essere memorizzate nella cache e impediamo che i risultati vengano eliminati dalle query che non abbiamo bisogno di memorizzare nella cache.) – spencer7593

risposta

9

Non calcolare l'ultimo giorno del mese. Calcola invece il primo giorno del mese successivo.

vostra query può essere come questo

WHERE t.mydatetimecol >= '2015-05-01' 
    AND t.mydatetimecol < '2015-05-01' + INTERVAL 1 MONTH 

Si noti che stiamo facendo un confronto meno di, non un "minore o uguale a" ... questo è molto conveniente per il confronto e TIMESTAMP Colonne DATETIME, che possono includere una porzione di tempo.

Si noti che un confronto BETWEEN è un "minore o uguale a". Per ottenere un confronto equivalente alla query precedente, avremmo bisogno di fare

WHERE t.mydatetimecol 
     BETWEEN '2015-05-01' AND '2015-05-01' + INTERVAL 1 MONTH + INTERVAL -1 SECOND 

(Questo presuppone che la risoluzione di DATETIME e TIMESTAMP è giù per un secondo. In altri database, come SQL Server, la risoluzione è più fine di un secondo, quindi avremmo il potenziale di perdere una riga con valore di '2015-05-31 23: 59: 59.997'. Non abbiamo un problema del genere con meno del primo giorno del confronto del mese successivo ... < '2015-06-01'

Non c'è bisogno di fare il calcolo del mese o della data da soli, lascia che MySQL lo faccia per te. Se mordi con l'aggiunta di 1 al mese, devi gestire il rollover da dicembre a Gennaio, e incremen t l'anno. MySQL ha tutto ciò che è già integrato.

+0

Nice job spencer – AsConfused

3

date('t', strtotime("$year-$month-01")) darà giorni del mese

+2

È una domanda sul rendimento, non su come fare una domanda. – chris85

+0

Alla domanda "come fare" per questo compito specifico è stato chiesto alla fine però. Penso che BETWEEN sarebbe un artista migliore, e potremmo approfondirlo più tardi se qualcun altro non ci riesce prima. –

Problemi correlati