My MySQL is not strong, so please forgive any rookie mistakes. Short version:
SELECT locId, count, avg FROM destAgg_geo is much slower than SELECT * from destAgg_geo
prtt.destAgg is a table with a key on dst_ip (PRIMARY)
mysql> describe prtt.destAgg; +---------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+------------------+------+-----+---------+-------+ | dst_ip | int(10) unsigned | NO | PRI | 0 | | | total | float unsigned | YES | | NULL | | | avg | float unsigned | YES | | NULL | | | sqtotal | float unsigned | YES | | NULL | | | sqavg | float unsigned | YES | | NULL | | | count | int(10) unsigned | YES | | NULL | | +---------+------------------+------+-----+---------+-------+
geoip.blocks is a table with a key for startIpNum and endIpNum (PRIMARY)
mysql> describe geoip.blocks; +------------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+------------------+------+-----+---------+-------+ | startIpNum | int(10) unsigned | NO | MUL | NULL | | | endIpNum | int(10) unsigned | NO | | NULL | | | locId | int(10) unsigned | NO | | NULL | | +------------+------------------+------+-----+---------+-------+
destAgg_geo is a view:
CREATE VIEW destAgg_geo AS SELECT * FROM destAgg JOIN geoip.blocks ON destAgg.dst_ip BETWEEN geoip.blocks.startIpNum AND geoip.blocks.endIpNum;
Here's an optimization plan to select *:
mysql> explain select * from destAgg_geo; +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+ | 1 | SIMPLE | blocks | ALL | start_end | NULL | NULL | NULL | 3486646 | | | 1 | SIMPLE | destAgg | ALL | PRIMARY | NULL | NULL | NULL | 101893 | Range checked for each record (index map: 0x1) | +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+
Here's an optimization plan to select with specific columns:
mysql> explain select locId,count,avg from destAgg_geo; +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+ | 1 | SIMPLE | destAgg | ALL | PRIMARY | NULL | NULL | NULL | 101893 | | | 1 | SIMPLE | blocks | ALL | start_end | NULL | NULL | NULL | 3486646 | Range checked for each record (index map: 0x1) | +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+
Here's the optimization plan for each column from destAgg and only the locId column from geoip.blocks:
mysql> explain select dst_ip,total,avg,sqtotal,sqavg,count,locId from destAgg_geo; +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+ | 1 | SIMPLE | blocks | ALL | start_end | NULL | NULL | NULL | 3486646 | | | 1 | SIMPLE | destAgg | ALL | PRIMARY | NULL | NULL | NULL | 101893 | Range checked for each record (index map: 0x1) | +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+
Delete any column except dst_ip and the validation range is reset to blocks:
mysql> explain select dst_ip,avg,sqtotal,sqavg,count,locId from destAgg_geo; +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+ | 1 | SIMPLE | destAgg | ALL | PRIMARY | NULL | NULL | NULL | 101893 | | | 1 | SIMPLE | blocks | ALL | start_end | NULL | NULL | NULL | 3486646 | Range checked for each record (index map: 0x1) | +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+
which is then much slower. What's going on here?
(Yes, I could just use the query results and process from there, but I would like to know what is happening and why)
EDIT - EXPLAIN in the VIEW request:
mysql> explain SELECT * FROM destAgg JOIN geoip.blocks ON destAgg.dst_ip BETWEEN geoip.blocks.startIpNum AND geoip.blocks.endIpNum; +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+ | 1 | SIMPLE | blocks | ALL | start_end | NULL | NULL | NULL | 3486646 | | | 1 | SIMPLE | destAgg | ALL | PRIMARY | NULL | NULL | NULL | 101893 | Range checked for each record (index map: 0x1) | +----+-------------+---------+------+---------------+------+---------+------+---------+------------------------------------------------+