Запрос из 3 таблиц, длится вечно - PullRequest
0 голосов
/ 22 марта 2019

Я использую mysql-workbench 6.3 на Ubuntu 18.04.

У меня есть три таблицы, созданные следующим образом:

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 записей.

В чем проблема?Можете ли вы помочь мне выполнить запрос?

1 Ответ

0 голосов
/ 22 марта 2019

Лучший способ иметь дело с доменами - это использовать сгенерированные столбцы , на которых есть функция reverse , и индексировать эти сгенерированные столбцы. Таким образом, значительное количество запросов может быть 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 | <em>null</em>       | range | rev_domain    | rev_domain | 2003    | <em>null</em> |    1 |   100.00 | Using where; Using index

дБ <> скрипка здесь

...