MySql запрос, где условие медленно в большой таблице - PullRequest
0 голосов
/ 23 декабря 2011

У меня есть таблица (ip2country) из 1,5 миллиона записей, и я выполняю следующий запрос, который занимает более 4 секунд Моя структура таблицы

CREATE TABLE `ip2country` (
  `beginIPNum` bigint(20) DEFAULT NULL,
  `endIPNum` bigint(20) DEFAULT NULL,
  `countryId` varchar(4) DEFAULT NULL,
  `countryName` varchar(50) DEFAULT NULL,
  `state` varchar(50) DEFAULT NULL,
  `city` varchar(50) DEFAULT NULL,
  KEY `index1` (`beginIPNum`,`endIPNum`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8
PARTITION BY RANGE  COLUMNS(beginIPNum,endIPNum)
(PARTITION p0 VALUES LESS THAN (16777216,16777216) ENGINE = MyISAM,
 PARTITION p1 VALUES LESS THAN (251658240,251658240) ENGINE = MyISAM,
 PARTITION p2 VALUES LESS THAN (503316480,503316480) ENGINE = MyISAM,
 PARTITION p3 VALUES LESS THAN (754974720,754974720) ENGINE = MyISAM,
 PARTITION p4 VALUES LESS THAN (1006632960,1006632960) ENGINE = MyISAM,
 PARTITION p5 VALUES LESS THAN (1258291200,1258291200) ENGINE = MyISAM,
 PARTITION p6 VALUES LESS THAN (1509949440,1509949440) ENGINE = MyISAM,
 PARTITION p7 VALUES LESS THAN (1761607680,1761607680) ENGINE = MyISAM,
 PARTITION p8 VALUES LESS THAN (2013265920,2013265920) ENGINE = MyISAM,
 PARTITION p9 VALUES LESS THAN (2264924160,2264924160) ENGINE = MyISAM,
 PARTITION p10 VALUES LESS THAN (2516582400,2516582400) ENGINE = MyISAM,
 PARTITION p11 VALUES LESS THAN (2768240640,2768240640) ENGINE = MyISAM,
 PARTITION p12 VALUES LESS THAN (3019898880,3019898880) ENGINE = MyISAM,
 PARTITION p13 VALUES LESS THAN (3271557120,3271557120) ENGINE = MyISAM,
 PARTITION p14 VALUES LESS THAN (3523215360,3523215360) ENGINE = MyISAM,
 PARTITION p15 VALUES LESS THAN (3774873600,3774873600) ENGINE = MyISAM,
 PARTITION p16 VALUES LESS THAN (4294967295,4294967295) ENGINE = MyISAM)

SELECT beginIPNum,endIPNum,countryId,countryName 
FROM sdportallog.ip2country 
WHERE 2130706433 BETWEEN beginIPNum AND endIPNum

Может кто-нибудь помочь мне, пожалуйста?

Ответы [ 4 ]

1 голос
/ 23 декабря 2011

Попробуйте

SELECT beginIPNum,endIPNum,countryId,countryName 
FROM sdportallog.ip2country            
WHERE beginIPNum  <= 2130706433 AND endIPNum >= 2130706433 
0 голосов
/ 20 января 2012

ВЫБЕРИТЕ beginIPNum, endIPNum, countryId, countryName ОТ sdportallog.ip2country ГДЕ 2130706433 МЕЖДУ beginIPNum И endIPNum ПРЕДЕЛ 1

0 голосов
/ 23 декабря 2011

Если вы в порядке с индексами. Вы можете попробовать следующий подход:

  1. Добавление разделов
  2. Добавить еще один столбец в таблицу
  3. Запрос на изменение

Разделы : Попробуйте добавить разделы (вы можете проверить RANGE и HASH). Правильную стратегию вы можете выбрать самостоятельно, просто заново создав таблицу и повторно выполнив запрос. Для HASH вы можете начать, например, с 10 разделов. Для диапазона вы можете:

  • inet_aton (1.0.0.0) ... inet_aton (255.0.0.0). Нет необходимости создавать 255 разделов.
  • если для какой-либо группы существует слишком много стран на группу X.0.0.0, вы можете попытаться сузить разделение и разделить на X.Y.0.0

Таблицы изменений : Я полагаю, что хорошей практикой является добавление параметра разделения в качестве столбца и его индексация. Но не стесняйтесь этого шага.

Изменения, связанные с вашим запросом : вам следует добавить фильтрацию значений хеша / диапазона. Например, если вы создаете разделы по X.0.0.0, вам нужно добавить что-то вроде where your_added_column = inet_aton(X.0.0.0) and your_base_condition

Попробуйте поиграть с разными типами разделов, количеством разделов.

Надеюсь, это поможет.

0 голосов
/ 23 декабря 2011

Оптимизация запроса заключается в создании пары индексов.Следующий скрипт создаст два индекса в таблице, по одному на каждое поле.

-- Create index on IPFrom
CREATE INDEX index_beginIPNum
    ON sdportallog.ip2country(beginIPNum)

-- Create index on IPTo
CREATE INDEX index_endIPNum
    ON sdportallog.ip2country(endIPNum)
...