Очень странно так:
mysql> explain select *from online where last < now()-interval 30 second and type=1;
+----+-------------+--------+------+---------------------------------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------------------------------+------+---------+------+------+-------------+
| 1 | SIMPLE | online | ALL | i_online_type_last,i_online_last_type | NULL | NULL | NULL | 24 | Using where |
+----+-------------+--------+------+---------------------------------------+------+---------+------+------+-------------+
mysql> explain select *from online where last < '2009-06-16 06:48:33' and type=1;
+----+-------------+--------+------+---------------------------------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------------------------------+------+---------+------+------+-------------+
| 1 | SIMPLE | online | ALL | i_online_type_last,i_online_last_type | NULL | NULL | NULL | 120 | Using where |
+----+-------------+--------+------+---------------------------------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> show index from online;
+--------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| online | 0 | PRIMARY | 1 | id | A | 24 | NULL | NULL | | BTREE | |
| online | 0 | account_id | 1 | account_id | A | 24 | NULL | NULL | | BTREE | |
| online | 1 | i_online_type_last | 1 | last | A | 2 | NULL | NULL | YES | BTREE | |
| online | 1 | i_online_type_last | 2 | type | A | 2 | NULL | NULL | | BTREE | |
| online | 1 | i_online_last_type | 1 | last | A | 2 | NULL | NULL | YES | BTREE | |
| online | 1 | i_online_last_type | 2 | type | A | 2 | NULL | NULL | | BTREE | |
+--------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
6 rows in set (0.00 sec)
Для тех, кто говорит, что это из-за размера стола:
mysql> explain select *from users where email='test@gmail.com';
+----+-------------+-------+-------+---------------+---------------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------------+---------+-------+------+-------+
| 1 | SIMPLE | users | const | u_users_email | u_users_email | 386 | const | 1 | |
+----+-------------+-------+-------+---------------+---------------+---------+-------+------+-------+
1 row in set (0.00 sec)
mysql> select count(*) from users;
+----------+
| count(*) |
+----------+
| 24 |
+----------+
1 row in set (0.00 sec)
Вот еще несколько подсказок:
mysql> explain select * from online where `last` > '2009-06-16 06:48:33' and type in (1,2);
+----+-------------+--------+-------+--------------------+--------------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+--------------------+--------------------+---------+------+------+-------------+
| 1 | SIMPLE | online | range | i_online_type_last | i_online_type_last | 13 | NULL | 2 | Using where |
+----+-------------+--------+-------+--------------------+--------------------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> explain select * from online where `last` < '2009-06-16 06:48:33' and type in (1,2);
+----+-------------+--------+------+--------------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+--------------------+------+---------+------+------+-------------+
| 1 | SIMPLE | online | ALL | i_online_type_last | NULL | NULL | NULL | 120 | Using where |
+----+-------------+--------+------+--------------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
Изменение '<' на '>' сделает его совершенно другим, почему?
Наконец-то я нашел исправление, потому что last
имеет значение по умолчанию "null", изменение этого столбца на "not null" приведет к работе индекса.
Но я понятия не имею, почему это может сделать его другим, какие-либо объяснения?