I'm using Google Cloud SQL (the micro server version) to run a couple of performance tests.
I want to do the following query:
select count(*) from table where A = valueA and B like "%input_string%";
+----------+
| count(*) |
+----------+
| 512997 |
+----------+
1 row in set (9.64 sec)
If I run them separately, I get:
select count(*) from table where A = valueA;
+----------+
| count(*) |
+----------+
| 512998 |
+----------+
1 row in set (0.18 sec)
select count(*) from table where B like "%input_string%";
+----------+
| count(*) |
+----------+
| 512997 |
+----------+
1 row in set (1.43 sec)
How is that difference in performance possible???
Both A and B columns have indexes as they are used to order tables in a web application.
Thx! EDIT: table schema
table | CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`A` varchar(9) DEFAULT NULL,
`B` varchar(50) DEFAULT NULL,
`C` varchar(10) DEFAULT NULL,
`D` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `A` (`A`),
KEY `B` (`B`)
) ENGINE=InnoDB AUTO_INCREMENT=512999 DEFAULT CHARSET=utf8
A option might be using a FULLTEXT INDEX
and using MATCH()
on it.
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`A` varchar(9) DEFAULT NULL,
`B` varchar(50) DEFAULT NULL,
`C` varchar(10) DEFAULT NULL,
`D` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY(A),
FULLTEXT INDEX(B)
) ENGINE=InnoDB AUTO_INCREMENT=512999 DEFAULT CHARSET=utf8
And a query rewrite
SELECT
count(*)
FROM
`table`
WHERE
A = 'A'
AND
B IN (
SELECT
B
FROM
`table`
WHERE
MATCH(B) AGAINST('+input_string' IN BOOLEAN MODE)
)
The inner SQL will filter down a possible result based on the FULLTEXT index.
And the outer SQL will do the other filtering.
You could also use a UNION ALL
now i think about it.
It should work on this questions CREATE TABLE
statement .
The general idea is to get two counts for both filters and pick the lowest as valid count.
Query
SELECT
MIN(counted) AS 'COUNT(*)' # Result 512997
FROM (
select count(*) AS counted from `table` where A = 'A' # Result 512998
UNION ALL
select count(*) from `table` where B like "%input_string%" # Result 512997
) AS counts