2013-12-05 2 views
0

Ниже запрос выполняется в 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) 

Как я переписать его оптимизировать.

ответ

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 

отчетливым требуется в случае, если имеется несколько строк соответствия, и вы хотите, чтобы посчитать каждую строку только один раз.

Обратите внимание на использование МЕЖДУ для ясности.

+0

привет, интересно, если a.id не является PK (или UNIQUE), и все записи имеют одинаковое значение. Я думаю, что a.id должен быть PK (или UNIQUE), тогда 'DISTINCT' не требуется. я прав? –

+0

Да, вы правы. Это прекрасно работает, спасибо! –

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 
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) 
Смежные вопросы