有没有其他方法来编写此查询

时间:2013-12-05 06:01:17

标签: mysql performance optimization

以下 18分钟

执行查询
SELECT COUNT(*) FROM psverify_interaction_numeric_ip_address a
WHERE EXISTS (
  SELECT 1 FROM Xwalk_GeoLiteCity_Blocks
  WHERE startIpNum <= a.numeric_ip_address AND endIpNum >= a.numeric_ip_address 
);
+----------+
| COUNT(*) |
+----------+
|      240 |
+----------+
1 row in set (18 min 2.00 sec)

如何重写它以进行优化。

3 个答案:

答案 0 :(得分:1)

你有一个相关的子查询;他们必须为每一行执行,所以他们通常是表现糟糕的人。

而是使用联接和COUNT(DISTINCT)

SELECT COUNT(DISTINCT a.id)
FROM psverify_interaction_numeric_ip_address a
JOIN Xwalk_GeoLiteCity_Blocks b
  ON a.numeric_ip_address BETWEEN startIpNum AND endIpNum

如果有多个匹配的行,并且您只想对每一行计数一次,则需要DISTINCT。

另请注意BETWEEN的使用是为了清晰。

答案 1 :(得分:0)

如果您确定该表存在,则可以使用内部联接表。 我不确定,但希望这应该有效,试试这个:

SELECT COUNT(*)
FROM psverify_interaction_numeric_ip_address a
INNER JOIN Xwalk_GeoLiteCity_Blocks b
ON b.startIpNum <= a.numeric_ip_address AND b.endIpNum >= a.numeric_ip_address 

答案 2 :(得分:0)

假设psverify_interaction_numeric_ip_address.id是PK或UNIQUE ..

SELECT COUNT(a.id)
FROM psverify_interaction_numeric_ip_address a
INNER JOIN Xwalk_GeoLiteCity_Blocks b
  ON b.startIpNum <= a.numeric_ip_address AND b.endIpNum >= a.numeric_ip_address

您还需要制作:

`ALTER TABLE Xwalk_GeoLiteCity_Blocks
    ADD INDEX(startIpNum),
    ADD INDEX (endIpNum)