Silakan lihat tabel ini:
mysql> desc s_p;
+-------------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| s_pid | int(10) unsigned | YES | MUL | NULL | |
| sm_id | int(10) unsigned | YES | MUL | NULL | |
| m_id | int(10) unsigned | YES | | NULL | |
| created | datetime | YES | | NULL | |
| s_date | datetime | YES | | NULL | |
| estimated_date | datetime | YES | MUL | NULL | |
+-------------------------+------------------+------+-----+---------+----------------+
Sekarang Lihatlah pertanyaan-pertanyaan ini:
mysql> select count(*) from s_p where estimated_date is null;
+----------+
| count(*) |
+----------+
| 190580 |
+----------+
1 row in set (0.05 sec)
mysql> select count(*) from s_p where estimated_date is not null;
+----------+
| count(*) |
+----------+
| 35640 |
+----------+
1 row in set (0.07 sec)
mysql> select count(*) from s_p;
+----------+
| count(*) |
+----------+
| 1524785 |
+----------+
Hitungan di atas tidak cocok. Sementara sesuai pemahaman saya:
Hitung dengan IS NULL
dan Hitung dengan IS NOT NULL
harus sama dengan menghitung saat ditanya tanpa klausa mana.
Ada ide tentang apa yang terjadi di sini?
================================================== =
Pembaruan pada 17 Februari 2012
Karena, saya menemukan bahwa banyak orang bertanya tentang jenis nilai yang diestimasi saat ini. Inilah jawabannya:
mysql> select distinct date(estimated_date) from s_p;
+----------------------+
| date(estimated_date) |
+----------------------+
| NULL |
| 2012-02-17 |
| 2012-02-20 |
| 2012-02-21 |
| 2012-02-22 |
| 2012-02-23 |
| 2012-02-24 |
| 2012-02-27 |
| 2012-02-28 |
+----------------------+
9 rows in set (0.42 sec)
Seperti yang Anda lihat di atas taksiran tanggal memiliki NULL atau nilai datetime yang valid. Tidak ada nol atau string kosong "".
Bisakah ini (masalah asli) terjadi jika indeks pada estim_date memiliki beberapa masalah?
================================================== =
Pembaruan pada 18 Februari 2012
Ini adalah show create output table:
| s_p | CREATE TABLE `s_p` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`s_id` int(10) unsigned DEFAULT NULL,
`sm_id` int(10) unsigned DEFAULT NULL,
`m_id` int(10) unsigned DEFAULT NULL,
`created` datetime DEFAULT NULL,
`estimated_date` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `sm_id` (`sm_id`),
KEY `estimated_date_index` (`estimated_date`) USING BTREE,
) ENGINE=InnoDB AUTO_INCREMENT=1602491 DEFAULT CHARSET=utf8 |
Sekali lagi, saya hanya dapat menduga indeks pada taksiran tanggal di sini.
Juga, versi server mysql adalah 5.5.12.
select count(*)
dan tidakselect count(estimated_date)
? Keduanya akan menghasilkan hasil yang berbeda karena NULL diabaikan jika hanya itu yang Anda hitung.SELECT COUNT(*),SUM(CASE WHEN estimated_date IS NULL THEN 1 ELSE 0 END),SUM(CASE WHEN estimated_date IS NOT NULL THEN 1 ELSE 0 END) from s_p
- yang seharusnya mendapatkan semua jumlah sekaligus.CHECK TABLE
? Mengingat liar jumlah baris penuh yang lebih besar, aku kiraDELETE
pergi ke suatu tempat gila.Jawaban:
Apakah Anda memiliki beberapa tanggal nol? Nilai datetime
0000-00-00 00:00:00
dianggap oleh MySQL untuk secara bersamaan memuaskanis null
danis not null
:Lihat: http://bugs.mysql.com/bug.php?id=940
Ini diklasifikasikan sebagai "bukan bug". Mereka menyarankan solusi: gunakan mode ketat, yang akan mengubah peringatan penyisipan menjadi kesalahan.
Setelah mengatakan semua itu, ini saja tidak dapat menjelaskan variasi liar dalam hasil yang Anda dapatkan (jumlah
is null
danis not null
jumlah harus melebihi jumlah yang tidak dibatasi) ...sumber
DATE
atauDATETIME
didefinisikan sebagaiNOT NULL
. Dalam pertanyaan di sini, kolom didefinisikan sebagai nullable. Namun bug ini, adalah alasan lain untuk menjalankan MySQL dalam mode ketat saja.@ypercube:
Saya baru-baru ini ditanya apakah saya pikir bug regresi "SELECT COUNT (DISTINCT) crash InnoDB ketika operan WHERE berada di Primary Key atau Unique Index" bisa menjadi akar dari ini.
Inilah jawaban saya (asal di sini):
http://www.chriscalender.com/?p=315&cpage=1#comment-1460
Saya tidak berpikir ini adalah bug yang sama. Bug ini lebih mengarah pada crash, dan membutuhkan SELECT COUNT (DISTINCT) khusus, ditambah operan WHERE ada di Primary Key atau indeks Unik.
Bug / masalah Anda tidak memiliki DISTINCT, itu tidak menabrak, dan indeks pada kolom datetime bukan kunci utama atau unik. Namun, ini agak aneh, jadi saya melakukan pencarian, dan menemukan bug ini, yang sepertinya lebih terlibat / terkait:
http://bugs.mysql.com/bug.php?id=60105
Sebenarnya, ini ditetapkan sebagai "bukan bug", tetapi ini menunjukkan / menggambarkan bagaimana Anda dapat mengalami perilaku aneh ketika Anda memiliki tanggal / waktu dengan '0000-00-00 ′ dan menggunakan IS NULL dan IS NOT NULL.
Saya ingin tahu apakah Anda memiliki baris '0000-00-00 ′ yang dapat memengaruhi penghitungan?
Perhatikan Dev yang berkomentar dalam laporan bug menyebutkan halaman ini juga:
Jika bukan itu, saya pasti akan merekomendasikan untuk meningkatkan dan mencoba ini pada 5.5 terbaru, yaitu 5.5.21 (per 2/22/2012), karena sudah 9 bulan (dan 9 rilis) sejak 5.5.12 sudah diterbitkan.
Catatan Anda harus dapat membuang tabel (dan data) dan mengimpornya ke contoh pengujian lain, hanya untuk mengujinya. Dengan begitu Anda tidak memengaruhi mesin produksi, dan Anda dapat mengatur instans pengujian dalam hitungan menit.
Kemudian, jika itu tidak membuat perbedaan apa pun, Anda akan dapat menguji beberapa item lain, seperti mungkin mengonversi tabel ke MyISAM untuk melihat apakah masalahnya adalah masalah global, atau hanya khusus untuk InnoDB.
Atau, saya perhatikan indeks pada 'taksiran tanggal' adalah:
KEY
estimated_date_index
(estimated_date
) MENGGUNAKAN BTREEPerhatikan "MENGGUNAKAN BTREE". Mungkin cobalah tanpa MENGGUNAKAN BTREE dan lihat apakah Anda masih melihat perilaku yang sama. (Atau hapus indeks sama sekali hanya untuk menguji .. semuanya akan membantu mempersempit masalah).
Semoga ini membantu.
sumber
Coba kueri
sumber
Saya melihat sesuatu yang menarik dalam tata letak tabel yang berteriak 'Saya tidak ingin menghitung'. Apa yang akan saya katakan hanyalah firasat.
Anda menjalankan kueri ini sebelumnya
Jalankan sebagai COUNT / GROUP BY
Anda harus mendapatkan jumlah pasti yang Anda cari.
Namun, mengapa penghitungan untuk NULL dan NOT NULL dapat dihitung dengan benar? Sekali lagi, ini hanya tebakan yang terpelajar.
Anda memiliki kolom yang
estimated_date
diindeks. Inilah yang saya ingin Anda coba:Itu bukan kesalahan ketik. Saya ingin Anda menjalankan
SHOW INDEX FROM s_p;
empat (4) kali. LihatlahCardinality
kolomnya. Karena tabels_p
di InnoDB, saya berharap kolom Kardinalitas berbeda setiap kali. Mengapa?InnoDB mendapatkan nilai Kardinalitas dengan memperkirakannya (TIDAK ADA PUN YANG DIMAKSUDKAN) dengan menghitung melalui entri halaman BTREE. Periksa variabel sistem Anda innodb_stats_on_metadata . Itu harus diaktifkan. Jika sudah diaktifkan, nonaktifkan dan jalankan kembali pertanyaan awal Anda untuk melihat apakah ada peningkatan. LAKUKAN HANYA INI SEBAGAI RESOR TERAKHIR !!!
Jadi, bukannya pertanyaan ini:
Mencoba
Ini akan memberi Anda hitungan baris dengan taksiran tanggal null.
Pendekatan lain yang Anda mungkin ingin bereksperimen dengan permintaan brute force ini menggunakan fungsi ISNULL :
Saya harap saran ini membantu !!!
sumber
Ini diharapkan. Untuk kolom yang nol 0 == NULL = "" dan seterusnya. Jadi cek pertama benar-benar mengembalikan baris di mana tidak ada tanggal yang ditetapkan atau dianggap analog dengan "0 / NULL"
sumber
0
tidak pernah sama denganNULL
. String kosong (''
) tidak sama denganNULL
baik, kecuali Anda bekerja dengan Oracle.