Самый быстрый способ, конечно, вообще не использовать базу данных, поскольку, если вы выполняете поиск вручную с оптимизированными данными, вы можете легко превзойти выбранную производительность поиска. Самый быстрый способ, при условии, что документы меняются не очень часто, - это создание индексных файлов и их использование для поиска ключевых слов. Индексный файл создается так:
Найти все уникальные слова в текстовом файле. Это разбивает текстовый файл по пробелам на слова и добавляет каждое слово в список, если он еще не найден в этом списке.
Возьмите все слова, которые вы нашли, и отсортируйте их по алфавиту; самый быстрый способ сделать это - использовать Three Way Radix QuickSort . Этот алгоритм сложно превзойти по производительности при сортировке строк.
Записать отсортированный список на диск, одним словом в строке.
Когда вы теперь хотите найти файл документа, полностью его проигнорируйте, вместо этого загрузите индексный файл в память и используйте двоичный поиск, чтобы выяснить, есть ли слово в индексном файле или нет. Бинарный поиск трудно превзойти при поиске больших отсортированных списков.
В качестве альтернативы вы можете объединить шаг (1) и шаг (2) в один шаг. Если вы используете InsertionSort (который использует бинарный поиск, чтобы найти правильную позицию вставки для вставки нового элемента в уже отсортированный список), у вас не только есть быстрый алгоритм, чтобы узнать, есть ли слово в списке или нет, в случае, если это не так, вы сразу получаете правильную позицию для вставки, и если вы всегда вставляете новые, подобные этим, у вас автоматически будет отсортированный список, когда вы перейдете к шагу (3).
Проблема в том, что вам нужно обновлять индекс при каждом изменении документа ... однако, разве это не будет верно и для решения для базы данных? С другой стороны, решение для базы данных дает вам некоторые преимущества: вы можете использовать его, даже если документы содержат так много слов, что индексные файлы больше не помещаются в память (маловероятно, поскольку даже список всех английских слов будет вписывается в память любого обычного пользователя ПК); однако, если вам нужно загрузить индексные файлы огромного количества документов, проблема с памятью может стать. Хорошо, вы можете обойти это, используя хитрые уловки (например, поиск непосредственно в файлах, которые вы отображали в память, используя mmap и т. Д.), Но это те же самые уловки, которые базы данных уже используют для быстрого поиска, поэтому зачем изобретать заново колесо? Кроме того, вы также можете предотвратить проблемы блокировки между поиском слов и обновлением индексов при изменении документа (то есть, если база данных может выполнить блокировку для вас или может выполнить обновление или обновления как элементарную операцию). Для веб-решения с AJAX-вызовами для обновления списка, вероятно, лучше использовать базу данных (мое первое решение вполне подходит, если это локально запущенное приложение, написанное на языке низкого уровня, таком как C).
Если вы чувствуете, что делаете все за один вызов select (что может быть неоптимально, но когда вы динамически обновляете веб-контент с помощью AJAX, это обычно оказывается решением, вызывающим наименьшую головную боль), вам нужно присоединиться ко всем трем таблицам все вместе. Пусть SQL немного ржавый, но я попробую:
SELECT COUNT(Document.idDoc) AS NumOfHits, Documents.Name AS Name, Documents.Location AS Location
FROM Documents INNER JOIN Word_Docs ON Word_Docs.idDoc=Documents.idDoc
INNER JOIN Words ON Words.idWord=Words_Docs.idWord
WHERE Words.Word IN ('Word1', 'Word2', 'Word3', ..., 'WordX')
GROUP BY Document.idDoc HAVING NumOfHits=X
Хорошо, может быть, это не самый быстрый выбор ... Я думаю, это можно сделать быстрее. В любом случае, он найдет все подходящие документы, которые содержат хотя бы одно слово, затем сгруппирует все одинаковые документы по идентификатору, посчитает, сколько было сгруппировано в togetehr, и, наконец, покажет результаты только там, где NumOfHits (количество слов, найденных в операторе IN) равно количеству слов в выражении IN (если вы ищете 10 слов, X равен 10).