简体   繁体   中英

execution of sql query using 'concat' with 'where' is slow

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM