Reputation: 21
I've write a sql query like
select max(area_prefix) as called_area, location
from tabile_1
where '10012451373' like concat(area_prefix,'%')
To extract the area_prefix
from the table_1
but this query is too much slow when I put this query on live server then it is taking 85.0sec
to fetch the data, take 10012451373
as a variable
. Is there any other option to increase the performance .
The situation is, that we get a call from the different regions from all over the world , so we have to take out the area_prefix
regarding that number so for that I've to see the whole area_prefix
in the table to tell the region from where the number belong this is where the concat
keyword came into help but it is taking too much time when it put on a live server.
There is different table regarding regions.
CREATE TABLE `tariff_50` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`area_prefix` varchar(255) NOT NULL,
`location` varchar(255) NOT NULL,
`initial_increment` varchar(255) NOT NULL,
`default_increment` varchar(255) NOT NULL,
`rate` varchar(255) NOT NULL,
PRIMARY KEY (`id`,`area_prefix`),
UNIQUE KEY `area_code` (`area_prefix`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=193542 DEFAULT CHARSET=latin1
How can I achieve this by without using CONCAT
keyword.
Upvotes: 0
Views: 1316
Reputation: 48850
The problem you have is that this query is performing a Full Table Scan. You do have an index on the area_prefix
column (since it's unique) but it's not being used by this query.
If you really want performance you would need to drastically change your query to make sure it uses the Index Seek operator while searching. The query shown below avoids using LIKE
and forces the use of =
. It's far uglier than the one you have, but it'll be very fast:
select max(area_prefix) from (
select area_prefix, location from tariff_50 where area_prefix = substring('10012451373', 1, 1)
union select area_prefix, location from tariff_50 where area_prefix = substring('10012451373', 1, 2)
union select area_prefix, location from tariff_50 where area_prefix = substring('10012451373', 1, 3)
union select area_prefix, location from tariff_50 where area_prefix = substring('10012451373', 1, 4)
union select area_prefix, location from tariff_50 where area_prefix = substring('10012451373', 1, 5)
union select area_prefix, location from tariff_50 where area_prefix = substring('10012451373', 1, 6)
union select area_prefix, location from tariff_50 where area_prefix = substring('10012451373', 1, 7)
union select area_prefix, location from tariff_50 where area_prefix = substring('10012451373', 1, 8)
union select area_prefix, location from tariff_50 where area_prefix = substring('10012451373', 1, 9)
union select area_prefix, location from tariff_50 where area_prefix = substring('10012451373', 1, 10)
) x;
I considered a maximum length of 10 characters for the area_prefix. If you have longer ones add more lines to this query.
I know it's ugly, but it's going to be blazing fast. :D
Upvotes: 1
Reputation: 21
This is what I got as an answer:
select max(area_prefix) as called_area,location from tariff_50
WHERE area_prefix = substring('10012451373', 1, 1)
OR area_prefix = substring('10012451373', 1, 2)
OR area_prefix = substring('10012451373', 1, 3)
OR area_prefix = substring('10012451373', 1, 4)
OR area_prefix = substring('10012451373', 1, 5)
OR area_prefix = substring('10012451373', 1, 6)
OR area_prefix = substring('10012451373', 1, 7) assume `area_prefix` length 7
Upvotes: 0