1

我正在构建一个动态查询以从我的数据库中选择删除的域名。目前有十几行,但我很快就会得到数据,其中将有多达 500,000 行的记录。

架构只是一个包含 4 列的表:

CREATE TABLE `DroppedDomains` (
  `domainID` int(11) NOT NULL AUTO_INCREMENT,
  `DomainName` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `DropDate` date DEFAULT NULL,
  `TLD` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`domainID`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

我没有创建架构,这是实时数据库架构。这是示例数据:

在此处输入图像描述

我已经构建了可能是下面最复杂的查询类型。标准如下:

选择任意数量的域

  1. 从“开始”这个词开始
  2. 以“结束”一词结尾
  3. 在域名中的任何位置包含单词“containsThis”
  4. 在域名的任何位置包含单词“ContainsThisToo”
  5. 至少包含一位数字
  6. 域名必须至少有 49 个字符。多字节需要算作一个字符(我使用了 CHAR_LENGTH )。
  7. 域名必须至少少于 65 个字符。
  8. TLD 必须是“org”
  9. DropDate 需要晚于2009-11-01

到目前为止,这是我的查询:

SELECT
*
FROM
DroppedDomains

WHERE

1=1

AND DomainName LIKE 'starts%ends'
AND DomainName LIKE '%containsThis%'
AND DomainName LIKE '%containsThisToo%'
AND DomainName LIKE '%-%'
AND DomainName REGEXP '[0-9]'
AND CHAR_LENGTH(DomainName) > 49
AND CHAR_LENGTH(DomainName) < 65
AND TLD = 'org'
AND DropDate > '2009-11-01'

这是我的问题

  1. 考虑到我将有 50 万行,如果我将该TLD列设为自己的表并仅将该列设为该TLD列的外键,它会极大地提高性能吗?将只有 5 个 TLD(com、net、org、info、biz)。我意识到现实世界中有更多的 TLD,但这个应用程序只有 5 个。用户不能指定自己的 TLD。

  2. 我知道,REGEXP500,000 行可能是灾难的根源。反正我可以避免REGEXP吗?

  3. 我可以对查询进行任何其他优化吗?像 mergeLIKE或使用其他功能,例如可能INSTR?我应该实现任何特定类型的缓存机制吗?

4

2 回答 2

3

当您有一个以常量前缀开头的 LIKE 模式并且您在该字段上有一个索引时,该索引可用于非常快速地找到以该前缀开头的行。幸运的是,您在这里遇到了这种情况:

AND DomainName LIKE 'starts%ends'

如果只有几个值以开头,starts那么这些行将很快被找到,其他表达式将只针对这些行进行测试。您可以通过运行检查索引是否被使用EXPLAIN SELECT ...

于 2011-03-12T21:42:01.483 回答
1

您应该根据计划使用的查询计划要创建的索引。

  • 如果您有仅按 DropDate 过滤的查询,那么 DropDate 上的索引将很有用。
  • 如果您有按 TLD 分组的查询,那么 TLD 上的索引将很有用。
  • 如果您的查询仅按域名的长度进行搜索,那么您可以考虑添加一个完全具有该域名长度的字段(以及对此的索引),这样每次运行查询时都不会计算长度。
  • 如果您有通过两个字段(例如 TLD 和 DropDate)搜索(过滤)的查询,那么您可能需要在这些字段上使用 2 列索引。
  • ETC...

如果您将使用的唯一查询是您提到的复杂查询,那么马克的建议(关于域名索引)是最好的。

关于TLD字段的问题1:

如果您真的只有少量(如 5 个)选项,并且您不打算使用所有可用的 tld,则可以使用ENUMtype

CREATE TABLE(
   ....
   tld ENUM('com', 'net', 'org', 'info', 'biz')
)
于 2011-03-13T02:40:40.913 回答