MySql查询WHERE条件在大表中慢

时间:2011-12-23 05:54:03

标签: mysql mysql-management

我有一张150万条记录的表(ip2country),我正在执行以下查询,这需要超过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 个答案:

答案 0 :(得分:1)

尝试

SELECT beginIPNum,endIPNum,countryId,countryName 
FROM sdportallog.ip2country            
WHERE beginIPNum  <= 2130706433 AND endIPNum >= 2130706433 

答案 1 :(得分:0)

查询优化是创建几个索引。以下脚本将在表上创建两个索引,每个字段对应一个。

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

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

答案 2 :(得分:0)

如果你对索引很好。您可以尝试以下方法:

  1. 添加分区
  2. 向表中添加其他列
  3. 更改查询
  4. 分区:尝试添加分区(您可以测试RANGE和HASH)。您可以通过自己的简单重新创建表并重新执行查询来选择正确的策略。对于HASH,您可以从10个分区开始。对于RANGE,您可以:

    • 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

    之类的内容

    尝试使用不同的分区类型,分区数量。

    希望它有所帮助。

答案 3 :(得分:0)

SELECT beginIPNum,endIPNum,countryId,countryName 来自sdportallog.ip2country 在哪里2130706433在beginIPNum和endIPNum之间 LIMIT 1