今天我们在SQL查询中发现了一个奇怪的行为(我们使用MySQL v5.6.36和InnoDB)。
采取此查询:
heat.exe dir ".\HarvestDir" -ag -sfrag -out harvestout.wxs
它返回以下结果:
mysql> SELECT count(*) FROM `inventory` WHERE `user_id` = 12345;
但是当运行以下查询时:
+----------+
| count(*) |
+----------+
| 495 |
+----------+
我们得到:
mysql> SELECT count(*) FROM `inventory` WHERE `user_id` = 12345 AND list_type = 3;
正如您所看到的,当查询受到限制时,结果计数会更大,这不应该发生。可能是什么原因造成的?它仅在master数据库中发生,而两个复制数据库都显示正确的结果。我们怀疑索引已损坏。如何在将来防止此类错误?
除了+----------+
| count(*) |
+----------+
| 1263 |
+----------+
之外的任何其他条件都会返回无效(太高)。
答案 0 :(得分:5)
不一致的结果可能意味着腐败的数据库或(如果幸运的话)腐败索引。尝试在不使用索引的情况下启动上述查询,看看你得到了什么:
SELECT count(*) FROM `inventory` USE INDEX () WHERE `user_id` = 12345;
SELECT count(*) FROM `inventory` USE INDEX () WHERE `user_id` = 12345 AND list_type = 3;
如果这只是一个索引,你可以尝试
OPTIMIZE TABLE `inventory`;
重新创建表和索引,然后对其执行 ANALYZE 。那是因为InnoDB不支持 REPAIR TABLE 。 另一种选择可能是尝试添加相同的索引,然后删除原始索引。
要对表执行检查,您还可以使用 CHECK TABLE ,但如果您想检查整个数据库,可以尝试
mysqlcheck --login-path=credentials --databases db_name
并优化所有表格
mysqlcheck --login-path=credentials --optimize --databases db_name
查看服务器的错误日志可能会提示您是否存在硬件问题或者您遇到的一些MySQL错误。
如果您的实际数据库已损坏,检查硬件然后尝试查看已损坏的内容以及如何通过与最近的备份进行比较来恢复它是有意义的。
答案 1 :(得分:-4)
有时SQL无法很好地处理'null'值。 试试这个:
mysql> SELECT count(*) FROM inventory WHERE (user_id = 12345 AND user_id is not null) AND (list_type = 3 AND list_type is not null);
如果不起作用,请尝试将'*'替换为主键。 例如:
mysql> SELECT count(user_id) FROM inventory WHERE (user_id = 12345 AND user_id is not null) AND (list_type = 3 AND list_type is not null);
虽然如果user_id
不能为'null',在这种情况下你不需要测试它。