从 3 个表中查询,永远持续
Query from 3 tables, lasts forever
我在 Ubuntu 18.04.
上使用 mysql-workbench
6.3
我创建了三个 table,如下所示:
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
第二个table:
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
第三个table:
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
我想做一个查询来识别三个 table 中的共享名称 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 columns that has the reverse 函数并对生成的列编制索引。这样,大量查询可以 WHERE domain LIKE CONCAT(reverse(const),'%')
并使用索引。
在查询中删除 http://
也是一种昂贵的方法。在生成的 function/index 中也使用它。
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
我在 Ubuntu 18.04.
mysql-workbench
6.3
我创建了三个 table,如下所示:
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
第二个table:
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
第三个table:
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
我想做一个查询来识别三个 table 中的共享名称 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 columns that has the reverse 函数并对生成的列编制索引。这样,大量查询可以 WHERE domain LIKE CONCAT(reverse(const),'%')
并使用索引。
在查询中删除 http://
也是一种昂贵的方法。在生成的 function/index 中也使用它。
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