Reputation: 384
Today we have spotted a strange behavior in SQL queries (we use MySQL v5.6.36 and InnoDB).
Take this query:
mysql> SELECT count(*) FROM `inventory` WHERE `user_id` = 12345;
It returns the following result:
+----------+
| count(*) |
+----------+
| 495 |
+----------+
But then when a following query is run:
mysql> SELECT count(*) FROM `inventory` WHERE `user_id` = 12345 AND list_type = 3;
We get:
+----------+
| count(*) |
+----------+
| 1263 |
+----------+
As you can see the result count is bigger when query is restricted which should not happen. What could be the cause of this? It happens in master database only while both replication databases show the correct results. We suspect corrupted indexes. How to prevent such errors in the future?
Any other conditions apart from list_type
return invalid (too high) counts as well.
Upvotes: 12
Views: 2066
Reputation: 2094
Inconsistent results could mean corrupt database or (if you're lucky) a corrupt index. Try to launch the above queries without using an index and see what you get:
SELECT count(*) FROM `inventory` USE INDEX () WHERE `user_id` = 12345;
SELECT count(*) FROM `inventory` USE INDEX () WHERE `user_id` = 12345 AND list_type = 3;
In case this is only an index you could try
OPTIMIZE TABLE `inventory`;
Which recreates the tables and indexes and then does ANALYZE on it. That's because InnoDB doesn't support REPAIR TABLE. Another option could be to try and add an identical index and then dropping the original index.
To perform checks on a table you could also use CHECK TABLE but if you wish to check the entire database you could try
mysqlcheck --login-path=credentials --databases db_name
and to optimize all tables
mysqlcheck --login-path=credentials --optimize --databases db_name
Looking at the error logs of the server might give you a hint on whether this was a hardware issue or some MySQL bug you've ran into.
In case your actual database is corrupt, it'll make sense to check the hardware and then try to see what has been corrupt and how to restore it by comparing to a recent backup.
Upvotes: 5
Reputation: 3
Sometimes SQL can't handle well the 'null' value. Try this:
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);
If it doesn't work, try to replace the '*' to the primary key. For example:
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);
Although if user_id
can't be 'null', in this case you don't need to test for that.
Upvotes: -4