mysql - 查询3张表,永远持续

标签 mysql database relational-database mysql-workbench database-performance

我在 Ubuntu 18.04 上使用 mysql-workbench 6.3。

我创建了三个表,如下所示:

CREATE TABLE `prefix_random` (
  `domain` varchar(500) NOT NULL,
   PRIMARY KEY (`domain`),
   UNIQUE KEY `domain_UNIQUE` (`domain`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1

注意:还有额外的 32 个字段,但我不查询它们,为简洁起见省略了它们。

示例:

domain
-----------------
sub.example.net

第二个表:

CREATE TABLE `noprefix_random` (
  `domain` varchar(500) NOT NULL,
  PRIMARY KEY (`domain`),
  UNIQUE KEY `domain_UNIQUE` (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

注意:还有额外的 32 个字段,但我不查询它们,为简洁起见省略了它们。

示例:

domain
----------------------
example.net

第三个表:

CREATE TABLE `new_random` (
  `new_domain` varchar(500) NOT NULL,
  PRIMARY KEY (`new_domain`),
  UNIQUE KEY `new_domain_UNIQUE` (`new_domain`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

注意:还有另外 3 个字段,但我不查询它们,为简洁起见省略了它们。

示例:

new_domain
------------------------
http://sub.example.com

我想进行一个查询来标识三个表中的共享名称 example.com,如下所示:

查询:

SELECT `new_random`.`new_domain`,`prefix_random`.`domain`,`noprefix_random`.`domain`
FROM `myscheme`.`new_random`
JOIN `myscheme`.`prefix_random`
# the substring to extract the part: sub.example.com
ON substring_index(`new_random`.`new_domain`,'http://',-1) = `prefix_random`.`domain`
JOIN `myscheme`.`noprefix_random`
# by adding sub, it becomes: sub.example
ON CONCAT('sub.',`noprefix_random`.`domain`) = `new_domain`,`prefix_random`; 

预期输出是:

http://sub.example.com, sub.example.com, example.com

查询将永远持续。如果我使用 L 将输出限制为较小的数字

LIMIT 10;

我得到了结果。记录数量不是太大。 prefix_random 包含 620062,noprefix_random 包含 、 62294 和 588380 条记录。

有什么问题吗?你能帮我运行查询吗?

最佳答案

处理域名的最佳方法是使用 generated columnsreverse对它们进行函数并对生成的列建立索引。这样,大量查询就可以 WHERE domain LIKE CONCAT(reverse(const),'%') 并使用索引。

在查询中删除 http:// 也是一种昂贵的方法。也在生成的函数/索引中使用它。

 CREATE TABLE `new_random` (
   `new_domain` varchar(500) NOT NULL,
   PRIMARY KEY (`new_domain`))

 INSERT INTO new_random VALUES ('http://a.b.c'),('http://d.e.f')

 ALTER TABLE new_random ADD no_https VARCHAR(500) AS (substring_index(`new_domain`,'http://',-1)), ADD KEY(no_https)

 ALTER TABLE new_random ADD rev_domain VARCHAR(500) AS (REVERSE(no_https)), ADD KEY(rev_domain)


 SELECT * FROM new_random
new_domain   | no_https | rev_domain
:----------- | :------- | :---------
http://a.b.c | a.b.c    | c.b.a     
http://d.e.f | d.e.f    | f.e.d     
 EXPLAIN SELECT new_domain FROM new_random WHERE rev_domain LIKE 'c.b.%'
id | select_type | table      | partitions | type  | possible_keys | key        | key_len | ref  | rows | filtered | Extra                   
-: | :---------- | :--------- | :--------- | :---- | :------------ | :--------- | :------ | :--- | ---: | -------: | :-----------------------
 1 | SIMPLE      | new_random | null       | range | rev_domain    | rev_domain | 2003    | null |    1 |   100.00 | Using where; Using index

db<> fiddle here

关于mysql - 查询3张表,永远持续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55290362/

相关文章:

mysql - MySQL 查询中的复杂 WHERE 子句 - [在 MySQL 中使用 VLOOKUP]

php - 按字母顺序排列 mysql 查询

C# SqlConnection 无法连接

database - 这些数据是否适合保存在数据库中?

database - 我怎样才能用关系代数找到MAX?

java - 从表中选择并插入到另一个表中

php - 连接具有多个结果的表,然后合并到一列中

php - 编码/解码并不总是有效 - Codeigniter

mysql - 带有 OneToOne 注释的数据库结构

sql - 根据另一个表中的数字在一个表中插入多行