首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于存储域名的推荐MySQL索引

用于存储域名的推荐MySQL索引
EN

Stack Overflow用户
提问于 2020-02-16 13:00:37
回答 2查看 358关注 0票数 1

我试图在MySQL数据库中存储大约1亿个域名,但是我无法找到在域名上使用的正确的索引方法。

问题是,类似的查询也将被执行:

代码语言:javascript
复制
SELECT id FROM domains WHERE domain LIKE '%.example.com'

代码语言:javascript
复制
SELECT id FROM domains WHERE domain LIKE 'example.%'

如果这样做更容易,那么‘%示例%’并不是一个要求,但最好是拥有/能够这样做是件好事。

正确的索引是什么?从左到右(例如.%)应该是直接向前的,但是从右到左(%.example.com)是有问题的,但是最常见的查询。

我在Linux上使用MariaDB 10.3。在PCI-e SSD上运行的DB,查找时间超过10秒的时间应该是“不可接受的”。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-16 17:27:44

您可以在表中使用一个虚拟永久列( rdomain ),其中虚拟函数以与REVERSE(domain).相反的顺序存储域名,因此可以从字符串的开头进行搜索,即搜索'%.mydomain.com‘->,其中rdomain类似于反向(’%.mydomain.com‘)。

代码语言:javascript
复制
CREATE TABLE `myreverse` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `domain` varchar(64) CHARACTER SET latin1 DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_domain` (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加列

代码语言:javascript
复制
ALTER TABLE myreverse
ADD COLUMN rdomain VARCHAR(64) AS  (REVERSE(domain)),
ADD KEY idx_rdomain (rdomain);

插入一些数据

代码语言:javascript
复制
INSERT INTO `myreverse` (`id`, `domain`)
VALUES
    (2, 'img.google.com'),
    (3, 'w3.google.com'),
    (1, 'www.coogle.com'),
    (4, 'www.google.de'),
    (5, 'www.mydomain.com');

参见数据

代码语言:javascript
复制
mysql> SELECT * from myreverse;
+----+------------------+------------------+
| id | domain           | rdomain          |
+----+------------------+------------------+
|  1 | www.google.com   | moc.elgoog.www   |
|  2 | img.google.com   | moc.elgoog.gmi   |
|  3 | w3.coogle.com    | moc.elgooc.3w    |
|  4 | www.google.de    | ed.elgoog.www    |
|  5 | www.mydomain.com | moc.niamodym.www |
+----+------------------+------------------+
5 rows in set (0.01 sec)

mysql> 

现在您可以使用反向顺序进行查询,MySQL可以使用索引。

查询

代码语言:javascript
复制
mysql> select * from myreverse WHERE rdomain like REVERSE('%.google.com');
+----+----------------+----------------+
| id | domain         | rdomain        |
+----+----------------+----------------+
|  3 | w3.google.com  | moc.elgoog.3w  |
|  2 | img.google.com | moc.elgoog.gmi |
+----+----------------+----------------+
2 rows in set (0.00 sec)

mysql> 

在这里,您可以看到优化器使用索引。

代码语言:javascript
复制
mysql> EXPLAIN select * from myreverse WHERE rdomain like REVERSE('%.google.com');
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type  | possible_keys | key         | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | myreverse | NULL       | range | idx_rdomain   | idx_rdomain | 195     | NULL |    2 |   100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)

mysql> 
票数 2
EN

Stack Overflow用户

发布于 2020-02-16 13:12:50

我不确定什么索引能帮到你。如果无法更改数据库,则选项似乎有限。您可以做的一件事是,如果您要连续运行子域和域查询,那么首先运行子域查询。这将有助于减少域查询必须覆盖的行数。

如果您将URL在子域和域之间拆分为数据库中的不同列,肯定会有所帮助。都有索引。然后您可以只查询子域和域。它应该会加快速度的。如果有大量的重复值,您应该对这些字段进行规范化,以便删除重复并加快查询速度。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60248716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档