ВЫБЕРИТЕ оптимизацию с использованием индексов

0

В настоящее время я работаю с набором данных по сходству слов. Данные очень просты - у вас есть пары слов и значение сходства. (Собака, кошка, 43000)

Я перевел необработанные данные в таблицу MySQL со следующей структурой:

word1_id: INT(11), Primary Key, Not Null

word2_id: INT(11), Primary Key, Not Null

value: INT(11), Not Null

При создании таблицы я также определил индекс (в дополнение к индексу первичного ключа):

PRIMARY: BTREE, #1 word1_id, #2 word2_id

Word2: BTREE, #1 word2_id, #2 word1_id

Есть 50 000 уникальных слов. Данные полностью статичны - как только вы впервые импортируете его в таблицу, ничего не меняется. Примером данных является:

word1_id ; word2_id ; value

1 ; 2 ; 48971754

1 ; 3 ; 75997417

1 ; 4 ; 18285783

..

1 ; 50000 ; 127

2 ; 3 ; 1046254

2 ; 4 ; 268081

...

Цель проста: для данного целевого слова (int) найдите наиболее похожие слова.

Для этого таблица должна найти все записи, в которых целевой INT (например, 436) находится либо в столбце 1 (436; 543; 475652), либо в столбце 2 (72; 436; 934454) и возвращает отсортированный результат, на основе столбца 3.

Моя проблема заключается в следующем:

При поиске целевой INT в первом столбце процесс выполняется быстро (например, 0,1 секунды).

SELECT
    value, word2_id
FROM
    cooccurrence
    WHERE
        word1_id = (436)
ORDER BY value DESC;

Однако делать то же самое и для инструкции WHERE, основанной на столбце 2, занимает очень много времени (например, 1,5-10 секунд)

SELECT
    value, word1_id
FROM
    cooccurrence
    WHERE
        word2_id = (436)
ORDER BY value DESC;

Вопросы:

  1. Почему гораздо медленнее делать WHERE на основе столбца 2, в отличие от столбца 1. Не следует ли индексировать таблицу "отсортированными" версиями данных на основе обоих столбцов?

  2. Является ли эта структура таблицы хорошим способом решения этой проблемы? Есть ли какие-то очевидные оптимиза ции?

  3. Конечная цель состоит в том, чтобы расстояние (колонка 3) было равно FLOAT и добавить четвертую колонку (INT), содержащую Год. Затем вы увидите, как меняется список большинства похожих слов с мишенью. Это означает, что данные (и таблица) будут резко увеличиваться - например, от нескольких гигабайт до сотен гигабайт. Это может существенно изменить ситуацию?

Теги:
where
indexing
bigdata

1 ответ

0
Лучший ответ
PRIMARY KEY(word1_id, word2_id),
INDEX(word2_id, value, word1_id),
INDEX(word1_id, value, word2_id)

Позвольте мне проанализировать

SELECT
    value, word2_id
FROM
    cooccurrence
    WHERE
        word1_id = (436)
ORDER BY value DESC;

Это происходит примерно так, используя INDEX(word2_id, value, word1_id):

  1. Найдите в этом индексе последнее вхождение word1_id = (436). (WHERE)
  2. Отсканируйте назад. (ORDER BY value DESC)
  3. В каждом элементе value, word2_id, (SELECT)

Если у вас будет только 50K слов, перейдите из INT SIGNED MEDIUMINT UNSIGNED в MEDIUMINT UNSIGNED. Это позволит сэкономить 6 байт в строке этой таблицы.

Как только вы добавили еще один столбец и изменили запрос, то, что я сказал, будет в основном неадекватным. Давайте посмотрим на SELECT который включает year.

При запросе запроса производительности EXPLAIN SELECT... Таким образом, мы можем указать на это, чтобы сказать, какие ключи вы получаете.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню