This query selects all the unique visitor sessions in a certain date range:
select distinct(accessid) from accesslog where date > '2009-09-01'
I have indexes on the following fields:
- accessid
- date
- some other fields
Here’s what explain looks like:
mysql> explain select distinct(accessid) from accesslog where date > '2009-09-01';
+----+-------------+-----------+-------+----------------------+------+---------+------+-------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+----------------------+------+---------+------+-------+------------------------------+
| 1 | SIMPLE | accesslog | range | date,dateurl,dateaff | date | 3 | NULL | 64623 | Using where; Using temporary |
+----+-------------+-----------+-------+----------------------+------+---------+------+-------+------------------------------+
mysql> explain select distinct(accessid) from accesslog;
+----+-------------+-----------+-------+---------------+----------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+---------------+----------+---------+------+---------+-------------+
| 1 | SIMPLE | accesslog | index | NULL | accessid | 257 | NULL | 1460253 | Using index |
+----+-------------+-----------+-------+---------------+----------+---------+------+---------+-------------+
Why doesn’t the query with the date clause use the accessid index?
Are there any other indexes I can use to speed up queries for distinct accessid’s in certain date spans?
Edit – Resolution
Reducing column width on accessid from varchar 255 to char 32 improved query time by ~75%.
Adding a date+accessid index had no effect on query time.
An index on
(date,accessid)could help. However, before tweaking indices I’d recommend checking the type of youraccessidcolumn.EXPLAINsays the key is 257 bytes long, which sounds like a lot for an ID column. Are you using aVARCHAR(256)foraccessid? If so, can’t you use a more compact type? If it’s a number, it should byINT(SMALLINT,BIGINT, whatever fits your needs) and if it’s an alphanumeric ID, can it really be 256 chars long? If its length is fixed, can’t you useCHAR(CHAR(32)for example) instead?