2 where 子句比分离查询慢
2 where clauses slower than separated queries
我正在使用 Google 云 SQL(微型服务器版本)运行 一些性能测试。
我想做以下查询:
select count(*) from table where A = valueA and B like "%input_string%";
+----------+
| count(*) |
+----------+
| 512997 |
+----------+
1 row in set (9.64 sec)
如果我 运行 他们分开,我得到:
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)
这种性能差异怎么可能???
A 和 B 列都有索引,因为它们用于在 Web 应用程序中排序 table。
谢谢!
编辑:
table 架构
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
一个选项可能正在使用 FULLTEXT INDEX
并在其上使用 MATCH()
。
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
并重写查询
SELECT
count(*)
FROM
`table`
WHERE
A = 'A'
AND
B IN (
SELECT
B
FROM
`table`
WHERE
MATCH(B) AGAINST('+input_string' IN BOOLEAN MODE)
)
里面的SQL会根据FULLTEXT索引过滤掉一个可能的结果。
而外层 SQL 将进行其他过滤。
你也可以使用 UNION ALL
现在我想到了。
它应该适用于这个问题 CREATE TABLE
statement 。
一般的想法是为两个过滤器获得两个计数并选择最低的作为有效计数。
查询
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
你有没有运行每次计时两次?如果不是,可能涉及缓存,这让您感到困惑。
where A = valueA and B like "%input_string%";
求 INDEX(A, B)
。注意:该复合索引不等同于您的两个单独索引。
如果你在 B
上使用 FULLTEXT
索引,那么这会更简单:
SELECT COUNT(*) FROM t
WHERE MATCH(B) AGAINST('+input_string' IN BOOLEAN MODE)
AND A = valueA
(使用子查询应该是不必要的,而且速度较慢。)
我正在使用 Google 云 SQL(微型服务器版本)运行 一些性能测试。
我想做以下查询:
select count(*) from table where A = valueA and B like "%input_string%";
+----------+
| count(*) |
+----------+
| 512997 |
+----------+
1 row in set (9.64 sec)
如果我 运行 他们分开,我得到:
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)
这种性能差异怎么可能???
A 和 B 列都有索引,因为它们用于在 Web 应用程序中排序 table。
谢谢! 编辑: table 架构
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
一个选项可能正在使用 FULLTEXT INDEX
并在其上使用 MATCH()
。
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
并重写查询
SELECT
count(*)
FROM
`table`
WHERE
A = 'A'
AND
B IN (
SELECT
B
FROM
`table`
WHERE
MATCH(B) AGAINST('+input_string' IN BOOLEAN MODE)
)
里面的SQL会根据FULLTEXT索引过滤掉一个可能的结果。
而外层 SQL 将进行其他过滤。
你也可以使用 UNION ALL
现在我想到了。
它应该适用于这个问题 CREATE TABLE
statement 。
一般的想法是为两个过滤器获得两个计数并选择最低的作为有效计数。
查询
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
你有没有运行每次计时两次?如果不是,可能涉及缓存,这让您感到困惑。
where A = valueA and B like "%input_string%";
求 INDEX(A, B)
。注意:该复合索引不等同于您的两个单独索引。
如果你在 B
上使用 FULLTEXT
索引,那么这会更简单:
SELECT COUNT(*) FROM t
WHERE MATCH(B) AGAINST('+input_string' IN BOOLEAN MODE)
AND A = valueA
(使用子查询应该是不必要的,而且速度较慢。)