【发布时间】:2016-11-17 17:48:42
【问题描述】:
我有一个包含存储为整数(500k 行)的 ips 的第一个表,第二个包含黑名单 ips 范围和黑名单原因(10M 行) 这是表结构:
CREATE TABLE `black_lists` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`ip_start` INT(11) UNSIGNED NOT NULL,
`ip_end` INT(11) UNSIGNED NULL DEFAULT NULL,
`reason` VARCHAR(3) NOT NULL,
`excluded` TINYINT(1) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `ip_range` (`ip_end`, `ip_start`),
INDEX `ip_start` ( `ip_start`),
INDEX `ip_end` (`ip_end`),
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=10747741
;
CREATE TABLE `ips` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'Id ips',
`idhost` INT(11) NOT NULL COMMENT 'Id Host',
`ip` VARCHAR(45) NULL DEFAULT NULL COMMENT 'Ip',
`ipint` INT(11) UNSIGNED NULL DEFAULT NULL COMMENT 'Int ip',
`type` VARCHAR(45) NULL DEFAULT NULL COMMENT 'Type',
PRIMARY KEY (`id`),
INDEX `host` (`idhost`),
INDEX `index3` (`ip`),
INDEX `index4` (`idhost`, `ip`),
INDEX `ipsin` (`ipint`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=675651;
我的问题是,当我尝试运行此查询时,没有使用索引,并且需要很长时间才能完成:
select i.ip,s1.reason
from ips i
left join black_lists s1 on i.ipint BETWEEN s1.ip_start and s1.ip_end;
我正在使用 MariaDB 10.0.16
【问题讨论】:
-
如果您编写的查询至少包含 一些 实际信息,从何处开始挖掘数据,则将使用索引。为什么不在问这样一个问题之前花 20 秒思考你做了什么?另外,您知道真正的索引是什么吗?让查询快速出乎意料并不是什么黑魔法。我建议您在就无法使用索引的查询寻求帮助之前,先挖掘一些有关索引是什么以及它们如何工作的信息,即使您有一个仙女许下的愿望 - 她无法使用此查询索引。
-
我问这个问题是因为这个查询使用了索引:“select s1.reason from black_lists s1 on 111111111 BETWEEN s1.ip_start and s1.ip_end;”,所以我想如果我做一个左连接它会就像这个循环一样
-
但是您在此处提供了一个 值,因此 MySQL 知道从哪里开始查找。如果您不提供实际值(例如 111111111 之类的数字),那么除了查看所有内容并吐出大量记录之外还能做什么?
标签: mysql indexing range left-join mariadb