MySQL SELECT WHERE datetime cocok dengan hari (dan belum tentu waktu)

127

Saya punya tabel yang berisi kolom datetime. Saya ingin mengembalikan semua catatan pada hari tertentu terlepas dari waktu. Atau dengan kata lain, jika meja saya hanya berisi 4 catatan berikut, maka hanya tanggal 2 dan 3 yang akan dikembalikan jika saya membatasi 2012-12-25.

2012-12-24 00:00:00
2012-12-25 00:00:00
2012-12-25 06:00:00
2012-12-26 05:00:00
pengguna1032531
sumber
Lihat jawaban oleh John Woo di stackoverflow.com/questions/14769026/…
ekerner

Jawaban:

326

TIDAK PERNAH menggunakan pemilih seperti DATE(datecolumns) = '2012-12-24'- ini adalah pembunuh kinerja:

  • itu akan menghitung DATE()untuk semua baris, termasuk yang tidak cocok
  • itu akan membuat tidak mungkin untuk menggunakan indeks untuk permintaan

Ini jauh lebih cepat untuk digunakan

SELECT * FROM tablename 
WHERE columname BETWEEN '2012-12-25 00:00:00' AND '2012-12-25 23:59:59'

karena ini akan memungkinkan penggunaan indeks tanpa perhitungan.

EDIT

Seperti yang ditunjukkan oleh Used_By_Already, pada saat sejak jawaban awal pada tahun 2012, telah muncul versi MySQL, di mana menggunakan '23: 59: 59 'sebagai hari akhir tidak lagi aman. Versi yang diperbarui harus dibaca

SELECT * FROM tablename 
WHERE columname >='2012-12-25 00:00:00'
AND columname <'2012-12-26 00:00:00'

Inti dari jawabannya, yaitu penghindaran pemilih pada ekspresi yang dihitung, tentu saja masih berlaku.

Eugen Rieck
sumber
Saya hendak berkomentar bahwa solusi a1ex07 tampaknya tidak sebagus yang lain. Setelah membaca posting Anda, mungkin saya perlu membalikkan pemikiran saya!
user1032531
2
Hanya diuji pada dua server di atas adalah JAUH (setidaknya 10x) lebih cepat dari tanggal () = '' terutama untuk tabel besar. Terima kasih
zzapper
1
@KonradViltersten Saya menggunakan cara yang sangat verbose untuk frasa kueri agar lebih mudah dibaca dan mengarahkan poin saya, tidak memperbaikinya. Jawaban oleh a1ex07 memiliki sintaks yang jarang.
Eugen Rieck
9
@KonradViltersten - Lebih baik lagi: WHERE col >= '2012-12-25' AND col < '2012-12-25' + INTERVAL 1 DAY. Ini menghindari 0 waktu dan bekerja untuk DATE, DATETIME, DATETIME(6), dll Dan penawaran dengan lompatan-hari, dll
Rick James
1
'2012-12-25 23:59:59' BUKAN VALID sebagai hari akhir, itu selalu merupakan ide yang buruk dan itu akan menyebabkan bug untuk versi MySQL yang mendukung ketepatan waktu sub-detik. Jauh lebih baik menggunakan pendekatan oleh Rick James (di atas) atau a1ex07 (jawaban lain)
Used_By_Already
34

... WHERE date_column >='2012-12-25' AND date_column <'2012-12-26'mungkin berpotensi bekerja lebih baik (jika Anda memiliki indeks pada date_column) daripada DATE.

a1ex07
sumber
1
Saya benar-benar bertanya-tanya apa yang lebih cepat - ini atau BETWEENsolusinya ... ada yang ditandai?
jave.web
6
Seharusnya tidak ada perbedaan. BETWEENhanyalah cara untuk menulis field >= value1 and fied<= value2.
a1ex07
1
Perhatikan bahwa per Manual MySQL: "Untuk hasil terbaik saat menggunakan BETWEEN dengan nilai tanggal atau waktu, gunakan CAST () untuk secara eksplisit mengkonversi nilai ke tipe data yang diinginkan. Contoh: Jika Anda membandingkan DATETIME dengan dua nilai DATE, konversikan DATE nilai ke nilai DATETIME. Jika Anda menggunakan konstanta string seperti '2001-1-1' dibandingkan dengan DATE, masukkan string ke DATE. " Jadi, kecuali mereka semua tipe yang sama, yang terbaik adalah melemparkan mereka secara eksplisit.
techdude
21

Anda bisa menggunakan %:

SELECT * FROM datetable WHERE datecol LIKE '2012-12-25%'
Ghilas BELHADJ
sumber
13
LIKE sepertinya selambat DATE (datetimecol). Lebih baik gunakan solusi Eugen atau a1ex07.
Marie Fischer
3
Ini tidak selalu tentang kecepatan. Jadi saya suka solusi ini. Itu jauh lebih mudah dibaca.
Simon Hansen