Por favor, veja esta tabela:
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 | |
+-------------------------+------------------+------+-----+---------+----------------+
Agora, dê uma olhada nessas 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 |
+----------+
As contagens acima não são correspondentes. Enquanto de acordo com o meu entendimento:
Contar com IS NULL
e Contar com IS NOT NULL
deve ser igual a contar quando consultado sem a cláusula where.
Alguma idéia do que está acontecendo aqui?
==================================================== =
Atualização em 17 de fevereiro de 2012
Desde então, descobri que muitas pessoas estão perguntando sobre o tipo de valores estimados atualmente na data. Aqui está a resposta:
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 você pode ver acima, o estimado_data possui valores NULL ou válidos para data e hora. Não há zeros ou cadeias vazias "".
Isso (problema original) pode acontecer se o índice na data_ estimada tiver algum problema / s?
==================================================== =
Atualização em 18 de fevereiro de 2012
Aqui está o show create table output:
| 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 |
Mais uma vez, só posso suspeitar de índice na estimativa_data aqui.
Além disso, a versão do servidor mysql é 5.5.12.
select count(*)
e nãoselect count(estimated_date)
? Esses dois retornarão resultados diferentes, pois os NULLs serão ignorados se essa for a única coisa que você 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 deve obter todas as contagens de uma só vez.CHECK TABLE
-lo? Considerando a contagem de linhas inteiras muito maior, eu acho que aDELETE
enlouqueceu em algum lugar.Respostas:
Você tem algumas datas zero? Os valores de data e hora de
0000-00-00 00:00:00
são considerados pelo MySQL para satisfazer simultaneamenteis null
eis not null
:Consulte: http://bugs.mysql.com/bug.php?id=940
Isso é classificado como "não é um bug". Eles sugerem uma solução alternativa: use o modo estrito, que converterá o aviso de inserção em erro.
Dito tudo isso, isso por si só não pode explicar a grande variação nos resultados que você está obtendo (a soma das contagens
is null
eis not null
deve exceder a contagem irrestrita) ...fonte
DATE
ouDATETIME
é definido comoNOT NULL
. Na pergunta aqui, a coluna é definida como anulável. Este bug, no entanto, é outro motivo para executar o MySQL somente no modo estrito.@ypercube:
Recentemente, fui perguntado se eu achava que o bug de regressão "SELECT COUNT (DISTINCT) trava o InnoDB quando o operando WHERE está na Chave Primária ou no Índice Único" pode estar na raiz disso.
Aqui está a minha resposta (originalmente aqui):
http://www.chriscalender.com/?p=315&cpage=1#comment-1460
Eu não acho que esse seja o mesmo bug. Esse bug é mais sobre a falha e requer uma SELECT COUNT (DISTINCT) especificamente, além do operando WHERE no chave primária ou no índice exclusivo.
Seu bug / problema não possui o DISTINCT, não está travando e o índice na coluna datetime não é uma chave primária nem exclusiva. No entanto, é um pouco estranho, então eu fiz algumas pesquisas e encontrei esse bug, que parece mais provável de estar envolvido / relacionado:
http://bugs.mysql.com/bug.php?id=60105
Na verdade, ele é designado como "não é um bug", mas mostra / descreve como você pode ter um comportamento estranho quando possui datas / datas com '0000-00-00' e usa IS NULL e IS NOT NULL.
Gostaria de saber se você tem alguma dessas linhas '0000-00-00' que pode estar afetando as contagens?
Observe que o desenvolvedor que comenta no relatório de erros também menciona esta página:
Se não for esse o caso, eu certamente recomendaria atualizar e tentar isso no 5.5 mais recente, que é 5.5.21 (a partir de 22/2/2012), já que faz 9 meses (e 9 lançamentos) desde o 5.5.12 foi liberado.
Observe que você deve despejar a tabela (e os dados) e importá-la para outra instância de teste, apenas para testá-la. Dessa forma, você não afeta uma máquina de produção e pode ter uma instância de teste configurada em minutos.
Então, se isso ainda não fizer diferença, você poderá testar outros itens, como converter a tabela para MyISAM para ver se o problema é global ou apenas específico para o InnoDB.
Ou notei que o índice em 'estimativa_data' era:
KEY
estimated_date_index
(estimated_date
) USANDO O BTREEObserve o "USANDO O BTREE". Talvez tente sem o USING BTREE e veja se você ainda vê o mesmo comportamento. (Ou remova o índice completamente apenas para testar .. tudo isso ajudará a diminuir o problema).
Espero que isto ajude.
fonte
Experimente a consulta
fonte
Vejo algo interessante no layout da tabela que grita 'Não sinto vontade de contar'. O que estou prestes a dizer é apenas um palpite.
Você executou esta consulta antes
Execute-o como COUNT / GROUP BY
Você deve obter as contagens definitivas que estava procurando.
No entanto, por que as contagens para NULL e NOT NULL são computadas corretamente? Novamente, este é apenas um palpite.
Você tem a coluna
estimated_date
indexada. Aqui está o que eu quero que você tente:Isso não é um erro de digitação. Quero que você corra
SHOW INDEX FROM s_p;
quatro (4) vezes. Olhe para aCardinality
coluna. Desde a tabelas_p
no InnoDB, espero que a coluna Cardinalidade seja diferente a cada vez. Por quê?O InnoDB obtém o valor de cardinalidade estimando-o (NO PUN INTENDED) contando através das entradas da página BTREE. Verifique a variável do sistema innodb_stats_on_metadata . Deve estar ativado. Se já estiver ativado, desative-o e execute novamente as consultas originais para ver se melhora as coisas. FAÇA ISSO SOMENTE COMO ÚLTIMO RECURSO !!!
Então, em vez dessas consultas:
Experimentar
Isso deve fornecer a contagem de linhas com uma data estimada não nula.
Outra abordagem que você pode querer experimentar com essa consulta de força bruta usando a função ISNULL :
Espero que estas sugestões ajudem !!!
fonte
Isso é esperado. Para uma coluna anulável, 0 == NULL = "" e assim por diante. Portanto, a primeira verificação retorna linhas onde nenhuma data foi definida ou sua percepção é análoga a "0 / NULL"
fonte
0
nunca é igual aNULL
. String vazia (''
) também não é a mesmaNULL
, a menos que você esteja trabalhando com o Oracle.