I need help in query optimization,I am having table with structure
Create Table: CREATE TABLE `ip_country_mapping` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`cron` bigint(20) NOT NULL,
`start_ip_number` bigint(20) NOT NULL,
`end_ip_number` bigint(20) NOT NULL,
`country` varchar(2) COLLATE utf8_bin NOT NULL,
`state` varchar(30) COLLATE utf8_bin DEFAULT NULL,
`city` varchar(30) COLLATE utf8_bin DEFAULT NULL,
`zip` varchar(30) COLLATE utf8_bin DEFAULT NULL,
`creation_date` datetime NOT NULL,
`last_updation_date` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UK_IP_COUNTRY_MAPPING_TEMP_START_IP_NUMBER` (`start_ip_number`),
UNIQUE KEY `UK_IP_COUNTRY_MAPPING_TEMP_END_IP_NUMBER` (`end_ip_number`),
KEY `FK_IP_COUNTRY_MAPPING_TEMP_CRON` (`cron`),
KEY `ind_ipscan` (`end_ip_number`,`start_ip_number`),
CONSTRAINT `FK_IP_COUNTRY_MAPPING_TEMP_CRON` FOREIGN KEY (`cron`) REFERENCES `cron` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2020168 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
1 row in set (0.00 sec)
The query to optimized is
SELECT ipcountrym0_.country as col_0_0_, ipcountrym0_.state as col_1_0_,ipcountrym0_.city as col_2_0_
FROM ip_country_mapping ipcountrym0_
WHERE ipcountrym0_.start_ip_number<=1376791568
AND ipcountrym0_.end_ip_number>=1376791568;
EXPLAIN plan is giving the output as
EXPLAIN SELECT ipcountrym0_.country as col_0_0_, ipcountrym0_.state as col_1_0_, ipcountrym0_.city as col_2_0_
FROM ip_country_mapping ipcountrym0_
WHERE ipcountrym0_.start_ip_number<=1376791568
AND ipcountrym0_.end_ip_number>=1376791568;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: ipcountrym0_
type: ALL
possible_keys: UK_IP_COUNTRY_MAPPING_TEMP_START_IP_NUMBER,UK_IP_COUNTRY_MAPPING_TEMP_END_IP_NUMBER,ind_ipscan
key: NULL
key_len: NULL
ref: NULL
rows: 2081584
Extra: Using where
If i add limit 1 to the above query,it scans 199999 rows.The output generated by this query is only one row.if i put order by clause in the above query with limit 1 then it scans only 2 rows.
EXPLAIN SELECT ipcountrym0_.country as col_0_0_, ipcountrym0_.state as col_1_0_, ipcountrym0_.city as col_2_0_
FROM ip_country_mapping ipcountrym0_
WHERE ipcountrym0_.start_ip_number<=1376791568
AND countrym0_.end_ip_number>=1376791568
ORDER BY id LIMIT 1;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: ipcountrym0_
type: index
possible_keys: UK_IP_COUNTRY_MAPPING_TEMP_START_IP_NUMBER,UK_IP_COUNTRY_MAPPING_TEMP_END_IP_NUMBER,ind_ipscan
key: PRIMARY
key_len: 8
ref: NULL
rows: 2
Extra: Using where
1 row in set (0.00 sec)
Is this the correct way my query is optimizing or there is some thing wrong the way i had tried to optimize. My Manager is are not agreeing with this optimization as he consider that the optimizer is first scanning the index column id and then the start ip number and end ip number which is not relevant.
Can somebody please explain how optimizer is working here and is this correct way the optimizing the query .It is argued that optimizer is showing wrong plan.
start_ip_number,end_ip_number) and then check the Explain PLAN. – Abdul Manaf Jul 18 '13 at 06:33