Я бы сделал хеш с ключом, являющимся первым словом из 9000 подстрок, а значением был бы массив со всеми подстроками с этим первым словом. Если много строк содержат одно и то же первое слово, вы можете использовать первые два слова.
Затем для каждого запроса, для каждого слова я бы посмотрел, есть ли это слово в хэше, а затем нужно сопоставить только те строки в массиве хеша, начиная с этой точки в строке, используя функцию индекса.
Предполагая, что сопоставление редкое, это было бы довольно эффективно. Один поиск по хешу на слово и минимальный поиск потенциальных совпадений.
Когда я пишу это, это напоминает мне о поиске ахораксика. (См. Algorithm :: AhoCorasick в CPAN.) Я никогда не использовал модуль, но алгоритм тратит много времени на построение конечного автомата из ключей поиска, поэтому поиск совпадения является суперэффективным. Я не знаю, обрабатывает ли реализация CPAN проблемы с границами слов.