Mysql 使用多个LIKE语句和REGEXP的查询能否更高效?
我正在构造一个动态查询,从数据库中选择删除的域名。目前有十几行,但我将很快获得数据,其中将有多达500000行的记录 架构只是一个包含4列的表:Mysql 使用多个LIKE语句和REGEXP的查询能否更高效?,mysql,sql,mysql5,Mysql,Sql,Mysql5,我正在构造一个动态查询,从数据库中选择删除的域名。目前有十几行,但我将很快获得数据,其中将有多达500000行的记录 架构只是一个包含4列的表: CREATE TABLE `DroppedDomains` ( `domainID` int(11) NOT NULL AUTO_INCREMENT, `DomainName` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, `DropDate` date DEFAULT NULL,
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
我没有创建模式,这是实时数据库模式。以下是示例数据:
我构建了下面可能是最复杂的查询类型。准则如下:
选择任意数量的域
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=1
和域名,如“开始%结束”
和域名,如“%containsThis%”
和域名,如“%containsthistoro%”
和类似“%-%”的域名
和域名REGEXP'[0-9]'
和字符长度(域名)>49
和字符长度(域名)<65
TLD='org'
和删除日期>'2009-11-01'
以下是我的问题
TLD
列作为自己的表,并将TLD
列作为外键,那么考虑到我将有50万行,这会极大地提高性能吗?只有5个TLD(com、net、org、info、biz)。我意识到现实世界中有更多的TLD,但这个应用程序只有5个TLD。用户无法指定自己的TLDREGEXP
和500000行可能会导致灾难。我是否可以避免使用REGEXP
Like
s或使用其他功能,例如可能INSTR
?我应该实现任何特定类型的缓存机制吗如果有一个以常量前缀开头的相似模式,并且该字段上有一个索引,则可以使用该索引快速查找以前缀开头的行。幸运的是,您正处于这种情况:
AND DomainName LIKE 'starts%ends'
如果只有少数值以
开始
开始,则将很快找到这些行,而其他表达式将仅针对这些行进行测试。您可以通过运行EXPLAIN SELECT…
检查是否使用了索引。当您有一个以常量前缀开头的相似模式,并且该字段上有一个索引时,可以使用索引快速查找以前缀开头的行。幸运的是,您正处于这种情况:
AND DomainName LIKE 'starts%ends'
如果只有少数值以
开始
开始,则将很快找到这些行,而其他表达式将仅针对这些行进行测试。您可以通过运行EXPLAIN SELECT…
检查是否使用了索引。您应该根据计划使用的查询计划要创建的索引
- 如果您有查询,请选择该筛选器 仅按DropDate,然后按 DropDate将非常有用
- 如果您有查询,请按分组 TLD,则TLD上的索引将 有用
- 如果您有需要搜索的查询 只有域名的长度,然后 您可以考虑添加字段域名长度 有一个索引,所以 长度不是每小时计算一次的 运行查询的时间
- 如果查询通过两个字段(例如TLD和DropDate)进行搜索(筛选),那么这些字段可能需要一个两列索引
- 等等
TLD
字段:
如果您真的只有少量(如5个)的选项,并且您不打算使用所有可用的TLD,那么您可以使用
您应该根据计划使用的查询计划要创建的索引
- 如果您有查询,请选择该筛选器 仅按DropDate,然后按 DropDate将非常有用
- 如果您有查询,请按分组 TLD,则TLD上的索引将 有用
- 如果您有需要搜索的查询 只有域名的长度,然后 您可以考虑添加字段域名长度 有一个索引,所以 长度不是每小时计算一次的 运行查询的时间
- 如果查询通过两个字段(例如TLD和DropDate)进行搜索(筛选),那么这些字段可能需要一个两列索引
- 等等
TLD
字段:
如果您真的只有少量(如5个)的选项,并且您不打算使用所有可用的TLD,那么您可以使用
注意:我知道我不应该使用
SELECT.*
,因为将来可能会添加更多的列,而选择不必要的列可能会影响性能。它仅用于演示/测试目的。注意:我知道我不应该使用SELECT.*
,因为将来可能会添加更多列,而选择不必要的列可能会影响性能。这只是为了演示/测试的目的。那么这是否意味着我的查询几乎已经尽可能地优化了?@meder:如果你有正确的索引,那么是的。您可能还想在这里考虑多栏索引。