Por favor, mire esta tabla:
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 | |
+-------------------------+------------------+------+-----+---------+----------------+
Ahora eche un vistazo a estas consultas:
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 |
+----------+
Los recuentos anteriores no coinciden. Mientras que según mi entendimiento:
Contar con IS NULL
y Contar IS NOT NULL
debe ser igual a contar cuando se consulta sin la cláusula where.
¿Alguna idea de lo que está pasando aquí?
================================================== =
Actualización el 17 de febrero de 2012
Desde entonces, descubrí que muchas personas preguntan sobre el tipo de valores que tiene estimada_fecha actualmente. Aquí está la respuesta:
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)
Como puede ver arriba, Estimated_date tiene valores NULL o de fecha y hora válidos. No hay ceros ni cadenas vacías "".
¿Puede suceder esto (problema original) si el índice en Estimated_date tiene algún problema?
================================================== =
Actualización el 18 de febrero de 2012
Aquí está la salida de la tabla show create:
| 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 |
Nuevamente, solo puedo sospechar el índice en la fecha estimada aquí.
Además, la versión del servidor mysql es 5.5.12.
select count(*)
y noselect count(estimated_date)
? Estos dos devolverán resultados diferentes ya que los NULL se ignoran si eso es lo único que está contando.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
que debería obtener todos los recuentos de una vez.CHECK TABLE
? Teniendo en cuenta el recuento de filas completas enormemente más grande, supongo que seDELETE
volvió loco en alguna parte.Respuestas:
¿Tienes algunas fechas cero?
0000-00-00 00:00:00
MySQL considera que los valores de fecha y hora satisfacenis null
yis not null
:Ver: http://bugs.mysql.com/bug.php?id=940
Esto se clasifica como "no es un error". Sugieren una solución alternativa: use el modo estricto, que convertirá la advertencia de inserción en un error.
Habiendo dicho todo eso, esto solo no puede explicar la variación salvaje en los resultados que está obteniendo (la suma de los conteos
is null
yis not null
debe exceder el conteo sin restricciones) ...fuente
DATE
oDATETIME
se define comoNOT NULL
. En la pregunta aquí, la columna se define como anulable. Sin embargo, este error es otra razón para ejecutar MySQL solo en modo estricto.@ypercube:
Recientemente me preguntaron si pensaba que el error de regresión "SELECT COUNT (DISTINCT) bloquea InnoDB cuando WHERE operand in Primary Key or Unique Index" podría estar en la raíz de esto.
Aquí está mi respuesta (originalmente aquí):
http://www.chriscalender.com/?p=315&cpage=1#comment-1460
No creo que este sea el mismo error. Este error es más acerca de la caída, y requiere un RECUENTO SELECCIONADO (DISTINCT) específicamente, más el operando WHERE está en la clave primaria o índice único.
Su error / problema no tiene DISTINCT, no se bloquea y el índice en la columna de fecha y hora no es una clave principal ni única. Sin embargo, es un poco extraño, así que hice un poco de búsqueda y me encontré con este error, que parece más probable que esté involucrado / relacionado:
http://bugs.mysql.com/bug.php?id=60105
En realidad, se designa como "no es un error", pero muestra / describe cómo puede encontrarse con un comportamiento extraño cuando tiene fechas / horas con '0000-00-00' y usa IS NULL y IS NOT NULL.
Me pregunto si tiene alguna de estas filas '0000-00-00' que podrían estar afectando los recuentos.
Tenga en cuenta que el desarrollador que comenta en el informe de errores también menciona esta página:
Si no es así, sin duda recomendaría actualizar y probar esto en la última versión 5.5, que es 5.5.21 (a partir del 22/02/2012), ya que han pasado 9 meses (y 9 versiones) desde 5.5.12 fue lanzado.
Tenga en cuenta que debería poder volcar la tabla (y los datos) e importarla a otra instancia de prueba, solo para probarla. De esa forma, no afecta a una máquina de producción y puede configurar una instancia de prueba en minutos.
Entonces, si eso no marca la diferencia, estaría en condiciones de probar algunos otros elementos, como quizás convertir la tabla a MyISAM para ver si el problema es global o específico para InnoDB.
O noté que el índice en 'Estimated_date' era:
CLAVE
estimated_date_index
(estimated_date
) USANDO BTREETenga en cuenta el "USO DE BTREE". Tal vez intente sin USAR BTREE y vea si todavía ve el mismo comportamiento. (O elimine el índice por completo solo para probar ... todo ayudará a reducir el problema).
Espero que esto ayude.
fuente
Prueba la consulta
fuente
Veo algo interesante en el diseño de la mesa que grita "No tengo ganas de contar". Lo que voy a decir es solo una corazonada.
Ejecutó esta consulta antes
Ejecútelo como COUNT / GROUP BY
Debes obtener los recuentos definitivos que estabas buscando.
Sin embargo, ¿por qué los recuentos para NULL y NOT NULL se calcularían correctamente? De nuevo, esto es solo una suposición educada.
Tienes la columna
estimated_date
indexada. Esto es lo que quiero que pruebes:Eso no es un error tipográfico. Quiero que corras
SHOW INDEX FROM s_p;
cuatro (4) veces. Mira laCardinality
columna Desde la tablas_p
en InnoDB, espero que la columna de Cardinalidad sea diferente cada vez. ¿Por qué?InnoDB obtiene el valor de Cardinalidad estimándolo (SIN PUNTO INTENCIONADO) contando a través de las entradas de la página BTREE. Verifique su variable de sistema innodb_stats_on_metadata . Debería estar habilitado. Si ya está habilitado, deshabilítelo y vuelva a ejecutar sus consultas originales para ver si mejora las cosas. ¡HAGA ESTO SOLO COMO ÚLTIMO RECURSO!
Entonces, en lugar de estas consultas:
Tratar
Esto debería darle el recuento de filas con una fecha estimada no nula.
Otro enfoque que puede experimentar con esta consulta de fuerza bruta utilizando la función ISNULL :
Espero que estas sugerencias ayuden !!!
fuente
Esto se espera. Para una columna que es anulable, 0 == NULL = "" y así sucesivamente. Por lo tanto, la primera comprobación en realidad devuelve filas donde no se estableció ninguna fecha o se percibe de forma análoga a "0 / NULL"
fuente
0
nunca es igual aNULL
. La cadena vacía (''
) tampoco es lo mismoNULL
, a menos que esté trabajando con Oracle.