Как быстрее искать миллионы записей в таблице SQL? - PullRequest
13 голосов
/ 04 мая 2011

У меня есть таблица SQL с миллионами доменных имен.Но теперь, когда я ищу, скажем,

SELECT * 
  FROM tblDomainResults 
 WHERE domainName LIKE '%lifeis%'

Требуется более 10 минут, чтобы получить результаты.Я пытался индексировать, но это не помогло.

Каков наилучший способ хранения этих миллионов записей и легкого доступа к этой информации за короткий промежуток времени?

На данный момент существует около 50 миллионов записей и 5 столбцов.

Ответы [ 7 ]

12 голосов
/ 04 мая 2011

Скорее всего, вы пытались использовать традиционный индекс, который нельзя использовать для оптимизации LIKE-запросов, если шаблон не начинается с фиксированной строки (например, «lifeis%»).

Что вам нужно для запроса, это полный-текстовый индекс.Большинство СУБД поддерживают это в наши дни.

6 голосов
/ 04 мая 2011

Предполагая, что ваша таблица строк на 50 миллионов содержит дубликаты (возможно, это является частью проблемы), и предполагая, что SQL Server (синтаксис может измениться, но концепция похожа на большинство СУБД), другой вариант - хранить домены в поискетаблица, например

CREATE TABLE dbo.Domains
(
    DomainID INT IDENTITY(1,1) PRIMARY KEY,
    DomainName VARCHAR(255) NOT NULL
);
CREATE UNIQUE INDEX dn ON dbo.Domains(DomainName);

Когда вы загружаете новые данные, проверьте, являются ли какие-либо из доменных имен новыми, и вставьте их в таблицу Домены.Затем в вашей большой таблице вы просто включаете DomainID.Это не только уменьшит размер вашей таблицы строк на 50 миллионов, но и сделает поиск более эффективным.

SELECT * -- please specify column names
FROM dbo.tblDomainResults AS dr
INNER JOIN dbo.Domains AS d
ON dr.DomainID = d.DomainID
WHERE d.DomainName LIKE '%lifeis%';

Конечно, за исключением самых маленьких таблиц, это всегда поможет избежать предложений LIKE.с лидирующим подстановочным знаком.

6 голосов
/ 04 мая 2011

Полнотекстовая индексация - это самый лучший вариант здесь - то, как это будет сделано, будет зависеть от используемой СУБД.Столбец, сопоставленный с шаблоном , будет повышать производительность, но, судя по звукам, вы попробовали это, и это не очень помогло.

5 голосов
/ 04 мая 2011

Прекратить использование оператора LIKE. Вы можете использовать полнотекстовый поиск , но для этого потребуется таблица MyISAM, и это не очень хорошее решение.

Я бы рекомендовал вам изучить доступные сторонние решения, такие как Lucene и Sphinx .
Они будут превосходить.

3 голосов
/ 04 мая 2011

Одна вещь, которую вы могли бы рассмотреть, это наличие отдельной поисковой системы для таких поисков. Например, вы можете использовать сервер SOLR (lucene) для поиска и получения идентификаторов записей, соответствующих вашему поиску, а затем извлекать данные из базы данных по идентификатору. Даже если сделать два разных звонка, вполне вероятно, что он окажется быстрее.

0 голосов
/ 04 мая 2011

Вы можете попробовать разбить домен на куски, а затем искать сами куски. Я делал нечто подобное несколько лет назад, когда мне нужно было искать слова в предложениях. У меня не было полнотекстового поиска, поэтому я разбил предложения на список слов и искал слова. Было очень быстро найти результаты, так как слова были проиндексированы.

0 голосов
/ 04 мая 2011

Индексы замедляются всякий раз, когда им приходится искать («поиск по закладкам») данные, которые сам индекс не содержит.Например, если ваш индекс имеет 2 столбца, ID и NAME, но вы выбираете * (всего 5 столбцов), база данных должна прочитать индекс для первых двух столбцов, а затем перейти к поиску остальных 3 столбцов вменее эффективная структура данных где-то еще.

В этом случае ваш индекс не может быть использован из-за "лайка".Это похоже на то, что в запросе не используется фильтр where, он будет полностью пропускать индекс, так как в любом случае ему нужно будет прочитать всю таблицу (это будет «сканирование таблицы»).Существует порог (я думаю, около 35-50%, где двигатель обычно переключается на это).

Короче говоря, маловероятно, что вам нужно все 50 миллионов строк из БД для производственного приложения, но если вы это сделаете ... используйте машину с большим объемом памяти и попробуйте методы, которые хранят эти данные в памяти.Возможно, лучшим вариантом будет DB без SQL - mongoDB, кушетка DB, кабинет Токио.Вещи как это.Удачи!

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