@nefedovgeka

Как быстрее подсчитать пересечение в таблице?

Имеем таблицу 150млн строк и 50 колонок, всего 7500млн ячеек, в одной ячейке одно слово, всего 10млн уникальных слов. Одно слово может встречаться в 200к строках.
Требуется вывести для каждого слова, набор слов с которым оно встречается(пересекается) в строке, с выводом количества таких встреч(пересечений).
Как это сделать быстрее?

Мне в голову приходит следующее: загрузить все это в БД, и по каждому уникальному домену выводить все строки где он встречается, (вывели 200к строк по 50 слов, всего 10млн слов) далее переводить все 10 млн в одну троку или столбец и отсортировать его, далее идти с начала троки или столба и считать группы одного слова и писать в базу сколько раз оно пересеклось с анализируемым и так по каждому из 10млн уникальных слов, в результате, после анализа одного слова, мы его исключаем из таблицы, так-как по нему уже все подсчитано, тем самым количество слов будет уменьшаться.

Поделитесь своим видением решения задачи.
  • Вопрос задан
  • 151 просмотр
Пригласить эксперта
Ответы на вопрос 1
@Akina
Сетевой и системный админ, SQL-программист.
Пример реализации "влоб" (синтаксис MySQL).

Структура:
CREATE TABLE test ( word0 VARCHAR(255),
                    word1 VARCHAR(255),
                    word2 VARCHAR(255),
                    word3 VARCHAR(255)
);


Запрос:
WITH 
cte1 AS (
    SELECT *, ROW_NUMBER() OVER () identity
    FROM test
),
cte2 AS (
    SELECT word0 word, identity FROM cte1 UNION ALL
    SELECT word1 word, identity FROM cte1 UNION ALL
    SELECT word2 word, identity FROM cte1 UNION ALL
    SELECT word3 word, identity FROM cte1 
)
SELECT LEAST(t1.word, t2.word), GREATEST(t1.word, t2.word), COUNT(DISTINCT identity)
FROM cte2 t1
JOIN cte2 t2 USING( identity )
WHERE t1.word > t2.word
GROUP BY 1, 2;

DEMO fiddle

Но надо чётко понимать что на заявленных объёмах запрос умрёт навсегда, вместе с сервером.

Для того, чтобы получить хоть сколько-нибудь вменяемое время обработки, надо, во-первых, выполнить нормализацию (преобразование, которое выполняют оба CTE) в статическую проиндексированную таблицу, во-вторых, получать данные не для всего массива сразу, а для достаточно узкого набора слов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы