There is an InnoDB table consisting of three columns.
+------------+---------------------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +------------+---------------------+------+-----+-------------------+-----------------------------+ | url_id | bigint(20) unsigned | NO | PRI | 0 | | | visitor_id | bigint(20) unsigned | YES | MUL | NULL | | | visit_time | timestamp | NO | MUL | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | +------------+---------------------+------+-----+-------------------+-----------------------------+
In table 2+ million lines. I need to select values that have visit_time > "2016-01-01"
. All fields are indexed.
The problem is that if I do this using visit_time, it will take a very long time.
mysql> SELECT COUNT(lu1.visitor_id) -> FROM log_url as lu1 -> WHERE lu1.visit_time > "2016-01-01"; +-----------------------+ | COUNT(lu1.visitor_id) | +-----------------------+ | 787719 | +-----------------------+ 1 row in set (2,71 sec)
And if done through visitor_id, it turns out much faster.
mysql> SELECT COUNT(lu1.visitor_id) -> FROM log_url as lu1 -> WHERE lu1.visitor_id > 600000; +-----------------------+ | COUNT(lu1.visitor_id) | +-----------------------+ | 787719 | +-----------------------+ 1 row in set (0,25 sec)
Tell me, what's the problem?
UPD: I forgot to attach EXPLAIN right away. It turns out at sampling by date it does not use an index. Although the index is.
mysql> EXPLAIN -> SELECT COUNT(lu1.visitor_id) -> FROM log_url as lu1 -> WHERE lu1.visitor_id > 600000; +----+-------------+-------+-------+---------------+------------+---------+------+---------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+------------+---------+------+---------+--------------------------+ | 1 | SIMPLE | lu1 | range | visitor_id | visitor_id | 9 | NULL | 1020864 | Using where; Using index | +----+-------------+-------+-------+---------------+------------+---------+------+---------+--------------------------+
visit_time:
mysql> EXPLAIN -> SELECT COUNT(lu1.visitor_id) -> FROM log_url as lu1 -> WHERE lu1.visit_time > "2016-01-01"; +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+ | 1 | SIMPLE | lu1 | ALL | visit_time | NULL | NULL | NULL | 2041728 | Using where | +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
EXPLAIN
, then you can think. - D-side