Пожалуйста, посмотрите на эту таблицу:
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 | |
+-------------------------+------------------+------+-----+---------+----------------+
Теперь взгляните на эти запросы:
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 |
+----------+
Количество выше не совпадают. Хотя по моему пониманию
Count с IS NULL
и Count с IS NOT NULL
должен быть равным count при запросе без предложения where.
Есть идеи о том, что здесь происходит?
================================================== знак равно
Обновление от 17 февраля 2012
С тех пор я обнаружил, что многие люди спрашивают о том, какие значения имеют оценочные значения в настоящее время. Вот ответ:
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)
Как вы можете видеть выше, сметное значение date_date либо NULL, либо допустимые значения даты и времени. Нет нулей или пустых строк "".
Может ли это (исходная проблема) произойти, если у индекса на оценочной дате есть какие-то проблемы?
================================================== знак равно
Обновление от 18 февраля 2012
Вот выходные данные show create 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 |
Опять же, я могу только подозревать индекс по оценочной дате здесь.
Также версия сервера mysql 5.5.12.
select count(*)
а нетselect count(estimated_date)
? Эти два будут возвращать разные результаты, так как NULL игнорируются, если это единственное, что вы рассчитываете.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
- который должен получить все подсчеты за один раз.CHECK TABLE
на нем? Учитывая дико большее количество полной строки, я предполагаю, чтоDELETE
сошел с ума , где - то.Ответы:
У вас есть нулевые даты? Значения даты
0000-00-00 00:00:00
и времени рассматриваются MySQL для одновременного удовлетворенияis null
иis not null
:Смотрите: http://bugs.mysql.com/bug.php?id=940
Это классифицируется как "не ошибка". Они предлагают обходной путь: используйте строгий режим, который преобразует предупреждение о вставке в ошибку.
Сказав все это, одно это не может объяснить дикие различия в результатах, которые вы получаете (сумма значений
is null
иis not null
должна превышать неограниченное количество) ...источник
DATE
илиDATETIME
определяется какNOT NULL
. В этом вопросе столбец определяется как обнуляемый. Эта ошибка, однако, является еще одной причиной для запуска MySQL только в строгом режиме.@ypercube:
Меня недавно спросили, не думал ли я, что в основе этого лежит ошибка регрессии «SELECT COUNT (DISTINCT), вызывающая сбой InnoDB, когда операнд WHERE находится в первичном ключе или уникальном индексе».
Вот мой ответ (изначально здесь):
http://www.chriscalender.com/?p=315&cpage=1#comment-1460
Я не думаю, что это та же ошибка. Эта ошибка больше касается сбоя и требует, в частности, SELECT COUNT (DISTINCT), плюс операнд WHERE находится в индексе первичного ключа или уникального индекса.
У вашей ошибки / проблемы нет DISTINCT, она не падает, и индекс в столбце datetime не является ни первичным ключом, ни уникальным. Тем не менее, это немного странно, поэтому я немного поискал и наткнулся на эту ошибку, которая, скорее всего, связана с этим:
http://bugs.mysql.com/bug.php?id=60105
На самом деле, он обозначен как «не ошибка», но показывает / описывает, как вы можете столкнуться со странным поведением, когда у вас есть даты / даты и время с «0000-00-00» и используются IS NULL и IS NOT NULL.
Интересно, есть ли у вас какие-либо из этих строк «0000-00-00», которые могут повлиять на счет?
Обратите внимание, что разработчик, который комментирует в отчете об ошибке, упоминает и эту страницу:
Если это не так, я бы определенно рекомендовал обновить и попробовать это на последней версии 5.5, то есть 5.5.21 (по состоянию на 22.02.2012), поскольку прошло 9 месяцев (и 9 выпусков) с 5.5.12. был выпущен.
Обратите внимание, что вы должны иметь возможность выгрузить таблицу (и данные) и импортировать ее в другой тестовый экземпляр, просто чтобы проверить его. Таким образом, вы не влияете на рабочую машину, и вы можете настроить тестовый экземпляр за считанные минуты.
Затем, если это все равно не поможет, вы сможете протестировать некоторые другие элементы, например, возможно, преобразовать таблицу в MyISAM, чтобы увидеть, является ли проблема глобальной или специфичной для InnoDB.
Или я заметил, что индекс для «оценочной даты» был:
КЛЮЧ
estimated_date_index
(estimated_date
) ИСПОЛЬЗУЯ BTREEОбратите внимание на «ИСПОЛЬЗОВАНИЕ BTREE». Возможно, попробуйте это без ИСПОЛЬЗОВАНИЯ BTREE и посмотрите, видите ли вы все то же поведение. (Или вообще уберите индекс, чтобы проверить ... это поможет сузить проблему).
Надеюсь это поможет.
источник
Попробуйте запрос
источник
Я вижу что-то интересное в макете стола, которое выкрикивает: «Мне не хочется считать». То, что я собираюсь сказать, это только догадка.
Вы выполняли этот запрос раньше
Запустите его как COUNT / GROUP BY
Вы должны получить точные счета, которые вы искали.
Тем не менее, почему значения для NULL и NOT NULL вычисляются правильно? Опять же, это просто обоснованное предположение.
У вас есть колонка
estimated_date
проиндексирована. Вот что я хочу, чтобы вы попробовали:Это не опечатка. Я хочу, чтобы ты бежал
SHOW INDEX FROM s_p;
четыре (4) раза. Посмотри наCardinality
колонку. Поскольку таблицаs_p
в InnoDB, я ожидаю, что столбец кардинальности будет отличаться каждый раз. Почему?InnoDB получает значение Cardinality, оценивая его (NO PUN INTENDED) путем подсчета записей на странице BTREE. Проверьте вашу системную переменную innodb_stats_on_metadata . Это должно быть включено. Если он уже включен, отключите его и повторно запустите исходные запросы, чтобы посмотреть, улучшится ли ситуация. ДЕЛАЙТЕ ЭТО ТОЛЬКО КАК ПОСЛЕДНИЙ КУРОРТ !!!
Итак, вместо этих запросов:
Пытаться
Это должно дать вам количество строк с ненулевым оценочным значением.
Другой подход, который вы можете поэкспериментировать с этим грубым запросом, используя функцию ISNULL :
Я надеюсь, что эти предложения помогут !!!
источник
Это ожидается. Для столбца, который обнуляется, 0 == NULL = "" и так далее. Таким образом, первая проверка фактически возвращает строки, в которых дата не была установлена или воспринимается аналогично «0 / NULL»
источник
0
никогда не равенNULL
. Пустая строка (''
) тоже не то же самоеNULL
, если вы не работаете с Oracle.