Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL计数不同-非常慢_Mysql_Database_Innodb - Fatal编程技术网

MySQL计数不同-非常慢

MySQL计数不同-非常慢,mysql,database,innodb,Mysql,Database,Innodb,我有一个非常大的MySQL InnoDB表,其结构如下: TABLE `whois_records` ( `record_id` int(10) unsigned NOT NULL, `domain_name` varchar(100) NOT NULL, `tld_id` smallint(5) unsigned DEFAULT NULL, `create_date` date DEFAULT NULL, `update_date` date DEFAULT NULL,

我有一个非常大的MySQL InnoDB表,其结构如下:

TABLE `whois_records` (
  `record_id` int(10) unsigned NOT NULL,
  `domain_name` varchar(100) NOT NULL,
  `tld_id` smallint(5) unsigned DEFAULT NULL,
  `create_date` date DEFAULT NULL,
  `update_date` date DEFAULT NULL,
  `expiry_date` date DEFAULT NULL,
  `query_time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

PRIMARY KEY (`record_id`)
UNIQUE KEY `domain_time` (`domain_name`,`query_time`)
INDEX `tld_id` (`tld_id`)
此表当前有1000万行。 它存储经常更新的域名详细信息。 因此,表中可以有多个相同域名的记录

TLD ID是域扩展类型的数值

问题是当我试图计算特定TLD的域名总数时

我尝试了以下3个SQL查询:

SELECT COUNT(DISTINCT(domain_name)) FROM `whois_records` WHERE tld_id=159
SELECT COUNT(*) FROM `whois_records` WHERE tld_id=159 GROUP BY domain_name
SELECT COUNT(*) FROM ( SELECT 1 FROM `whois_records` WHERE tld_id=159 GROUP BY domain_name) q
所有这三个都非常慢,需要5到10分钟。它还需要消耗大量的CPU来完成。TLD ID列上定义了索引,因此这些查询可能正在执行完整的索引扫描。还是很慢。TLD ID为159表示“.com”,这是数量最多的。因此,当搜索159时,速度最慢。对于不受欢迎的TLD,其域少于100个,相同的查询大约需要0.10秒。TLID159有大约600万条记录,占由1000万行组成的整个表的60%

有没有办法优化计算


随着表的增长,当前查询将花费更长的时间。所以,请任何人都能帮助我解决这个问题。是否需要更改表格?Plz帮助,谢谢:)

扩展索引以包含
域名

INDEX `tld_id` (`tld_id`, `domain_name`)
这应该使MySQL只使用索引而不是表数据来计算结果。如果两个值的组合都是唯一的,则添加一个新的唯一索引:

UNIQUE INDEX `new_index` (`tld_id`, `domain_name`)

我怀疑你能把它推得更远。如果速度仍然不够快,请考虑缓存计数器。

共享my.cnf配置文件和服务器配置(CPU、内存、驱动器类型、专用机器与否)。这一切都是为您指明正确方向的关键。第二个问题:tld_id可以为空吗?如果没有,请先更改方案,然后再执行其他操作。空字段(可以为空)大大降低了查找速度。感谢回复。是的,对于无法识别的域扩展,tld_id可以为NULL。我是否应该删除NULL,并将所有NULL更改为0?是的,如果应用程序逻辑可以处理这个问题。但这只是开始。请共享服务器配置问题是基数,如果您的条件返回表中的大多数行,索引搜索或松散的索引扫描(非常快)将变得无用。因此,您最希望的是索引扫描,即使mysql优化器认为这可能不是一个选项。简言之,索引的值太多,无法合理组合tld_id和域名,对于“example.com”这样的域,将有多行具有值:example.com,谢谢,您的方法有效。将“域名”包含在“tld_id”索引中,总查询时间和cpu使用率下降了75%。另外,MySQL解释现在在最后一列中显示“使用索引”。早些时候,它显示为“空”。但有一件事,桌子的大小增加了5%。这必须用于新索引。非常感谢您提供的解决方案:)@SadasivaUlaka综合指数帮助,太好了!减少了多少时间?这是否可以接受,或者您正在寻找其他优化技术?嗨,Anatoly,每天处理的TLD总共有1000个。因此,PHP脚本每天运行并执行SQL 1000次。以前,脚本大约需要20分钟才能完成。现在只需要90秒。另外,RDS CloudWatch监控系统不再显示CPU峰值,当此脚本运行时,CPU始终低于5%。这是我们可以接受的。顺便说一句,删除空值并将空值更改为0已完成。但是将列从NULL更改为notnull需要花费数小时,因此我们无法完成该更改。现在列使用NULL,就像以前一样
使用索引
很好——这表明查询完全是在BTree中为该索引完成的。表大小增加了5%——这包括索引吗?159行多少行?查询时间现在应该大致与该计数成比例。