Рекомендуется MySQL ИНДЕКС для хранения доменных имен - PullRequest
0 голосов
/ 16 февраля 2020

Я пытаюсь сохранить около 100 миллионов доменных имен в базе данных MySQL, но не могу найти правильный метод INDEX для использования с доменными именами.

Проблема в том, что * Также будет выполнено 1003 * LIKE запроса:

SELECT id FROM domains WHERE domain LIKE '%.example.com'

или

SELECT id FROM domains WHERE domain LIKE 'example.%'

Если это облегчает задачу, '% example%' не является обязательным требованием, но в лучшем случае это хорошо иметь / иметь возможность.

Какой индекс будет правильным для использовать? Слева направо (пример.%) Должно быть прямо вперед, но справа налево (% .example.com) проблематично c, но самый распространенный запрос.

Я использую MariaDB 10.3 для Linux. БД, работающая на PCI-e SSD, время поиска более 10 секунд должно совпадать "недопустимо"

Ответы [ 2 ]

1 голос
/ 16 февраля 2020

Вы можете потратить один виртуальный постоянный столбец (rdomain) в своей таблице, где виртуальная функция хранит имя домена в обратном порядке, например REVERSE (домен). , так что поиск возможен с начала строки, т.е. поиск для "% .mydomain.com" -> ГДЕ rdomain типа REVERSE ("%. mydomain.com

таблица

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;

добавить столбец

ALTER TABLE myreverse
ADD COLUMN rdomain VARCHAR(64) AS  (REVERSE(domain)),
ADD KEY idx_rdomain (rdomain);

вставить некоторые данные

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');

посмотреть данные

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 может использовать индекс.

query

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> 

Здесь вы можете видеть, что оптимизатор использует индекс.

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> 
0 голосов
/ 16 февраля 2020

Я не уверен, что индекс поможет вам здесь. Если вы не можете изменить базу данных, ваши возможности кажутся ограниченными. Одна вещь, которую вы можете сделать, - это если вы одновременно выполняете запрос как на поддомен, так и на домен, чтобы сначала выполнить запрос на поддомен. Это должно помочь уменьшить количество строк, которые должен охватывать запрос домена.

Это определенно поможет, если вы разделите URL-адрес между поддоменами и доменами на разные столбцы в базе данных. Есть индексы для них обоих. Тогда вы можете запросить только субдомены и только домены. Это должно ускорить процесс. И если повторяющихся значений много, вам следует нормализовать эти поля, чтобы исключить повторение и еще больше ускорить запросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...