MySQL:优化连接以查找不匹配的记录

MySQL:优化连接以查找不匹配的记录,mysql,join,left-join,query-optimization,inner-join,Mysql,Join,Left Join,Query Optimization,Inner Join,我们有一个主机管理系统(我们称之为CMDB)和一个DNS系统,每个系统使用不同的表。前者与后者同步,但手动更改会导致它们不同步。我想创建一个查询来查找CMDB中的别名,这些别名在DNS中没有匹配的条目(要么没有条目,要么名称/IP不同) 由于表的大小很大,并且需要频繁运行此查询,因此优化查询非常重要 以下是表格的外观: cmdb_record: id, ipaddr cmdb_alias: record_id, host_alias dns_entry: name, ipaddr cmdb_a

我们有一个主机管理系统(我们称之为CMDB)和一个DNS系统,每个系统使用不同的表。前者与后者同步,但手动更改会导致它们不同步。我想创建一个查询来查找CMDB中的别名,这些别名在DNS中没有匹配的条目(要么没有条目,要么名称/IP不同)

由于表的大小很大,并且需要频繁运行此查询,因此优化查询非常重要

以下是表格的外观:

cmdb_record: id, ipaddr
cmdb_alias: record_id, host_alias
dns_entry: name, ipaddr
cmdb_alias.record_id是来自cmdb_record.id的外键,因此一个IP地址可以有多个别名

到目前为止,我的想法如下:

SELECT cmdb_alias.host_alias, cmdb_record.ipaddr
FROM cmdb_record
INNER JOIN cmdb_alias ON cmdb_alias.record_id = cmdb_record.id
LEFT JOIN dns_entry
    ON dns_entry.ipaddr = cmdb_record.ipaddr
    AND dns_entry.name = cmdb_alias.host_alias
WHERE dns_entry.ipaddr IS NULL OR dns_entry.name IS NULL
这似乎可行,但需要很长时间才能运行。有更好的方法吗?谢谢

编辑:根据要求,以下是显示创建表。有很多额外的字段不是特别相关,但为了完整性而包括在内

Create Table: CREATE TABLE `cmdb_record` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip_version` int(11) DEFAULT NULL,
  `ipaddr` varchar(40) DEFAULT NULL,
  `ipaddr_numeric` decimal(40,0) DEFAULT NULL,
  `block_id` int(11) NOT NULL,
  `record_commented` tinyint(1) NOT NULL,
  `mod_time` datetime NOT NULL,
  `deleted` tinyint(1) NOT NULL,
  `deleted_date` datetime DEFAULT NULL,
  `record_owner` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ipaddr` (`ipaddr`),
  KEY `cmdb_record_fe30f0f7` (`ipaddr`),
  KEY `cmdb_record_2b8b575` (`ipaddr_numeric`),
  KEY `cmdb_record_45897ef2` (`block_id`),
  CONSTRAINT `block_id_refs_id_ed6ed320` FOREIGN KEY (`block_id`) REFERENCES `cmdb_block` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=104427 DEFAULT CHARSET=latin1

Create Table: CREATE TABLE `cmdb_alias` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `host_alias` varchar(255) COLLATE latin1_general_cs NOT NULL,
  `record_id` int(11) NOT NULL,
  `record_order` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `cmdb_alias_fcffc3bb` (`record_id`),
  KEY `alias_lookup` (`host_alias`),
  CONSTRAINT `record_id_refs_id_8169fc71` FOREIGN KEY (`record_id`) REFERENCES `cmdb_record` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=155433 DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs

Create Table: CREATE TABLE `dns_entry` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `rec_grp_id` varchar(40) NOT NULL,
  `parent_id` int(11) NOT NULL,
  `domain_id` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `type` varchar(6) DEFAULT NULL,
  `ipaddr` varchar(255) DEFAULT NULL,
  `ttl` int(11) DEFAULT NULL,
  `prio` int(11) DEFAULT NULL,
  `status` varchar(20) NOT NULL,
  `op` varchar(20) NOT NULL,
  `mod_time` datetime NOT NULL,
  `whodunit` varchar(50) NOT NULL,
  `comments` longtext NOT NULL,
  PRIMARY KEY (`id`),
  KEY `dns_entry_a2431ea` (`domain_id`),
  KEY `dns_entry_52094d6e` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=49437 DEFAULT CHARSET=utf8

如果您还没有,请在
dns\u条目(ipaddr,name)
上创建索引。这可能就是加快查询速度所需的全部内容。

显示创建表
--需要查看数据类型、索引、引擎等。感谢您的建议,补充说我看到了ipaddr的3种不同数据类型;最令人费解的是
十进制(40,0)
不需要删除
;您可以测试
已删除\u日期不是空的
。您正在处理IPv6吗?限制为39个字符。您会查看IP地址的“范围”吗?如果是这样的话,
11.22.33.44
就没用了。已经有了一个关于name的索引,但是没有关于ipaddr的索引。向IPADR添加索引大大加快了该查询的速度,使其在重复情况下可用。谢谢