Слова, уникальные для пользователя - где нет в - PullRequest
1 голос
/ 22 февраля 2011

У меня здесь очень простая структура таблицы. Просто список слов, связанных с простым user_id.

Word Table: 
    word - varchar(50)
    user_id - integer

Мне нужно найти слова, используемые одним пользователем, которые не используются другими пользователями. В настоящее время я делаю это, и он работает нормально на Postgresql (9.0.3) на 200 тыс. Слов (~ .3-.5 секунд) и полностью падает на MySQL (5.1.54) с теми же данными (5+ минут и все еще работает). Все используемые столбцы проиндексированы.

SELECT  
    word, count(word) as count
FROM 
    words
WHERE         
    word not in (select word from words where user_id <> 99 group by word)
    and user_id = 99
GROUP BY word
ORDER BY count desc LIMIT 20

1) Кто-нибудь знает лучший способ сделать это?

2) Кто-нибудь знает, почему он не работает на MySql?

РЕДАКТИРОВАТЬ: Это исправляет проблему в MySQL, от 5 минут + до 10-20 мс - спасибо Borealid

SELECT  
    word, count(word) as count
FROM 
    words
WHERE         
    word not in (select distinct word from words where user_id <> 99)
    and user_id = 99
GROUP BY word
ORDER BY count desc LIMIT 20

Спасибо.

1 Ответ

2 голосов
/ 22 февраля 2011

Попробуйте NOT EXISTS ():

SELECT  
    w1.word, 
    COUNT(w1.word) as count
FROM 
    words w1
WHERE         
    NOT EXISTS (
        SELECT 1 
        FROM 
            words w2 
        WHERE 
            w2.user_id <> 99 
        AND 
            w1.word = w2.word 
        )
AND 
    w1.user_id = 99
GROUP BY 
    w1.word
ORDER BY 
    count DESC 
LIMIT 20;

Убедитесь, что у вас есть индекс для user_id и слова (или комбинации), используйте объяснение, чтобы увидеть план запроса и то, что лучше всего подходит для вас.

====== Редактировать: также попробуйте решение LEFT JOIN, используя IS NULL:

SELECT
    w1.word,
    COUNT(w1.word) AS count
FROM
    words w1
        LEFT JOIN words w2 ON (w1.word = w2.word AND w1.user_id <> w2.user_id)
WHERE
    w1.user_id = 99
AND
    w2.word IS NULL
GROUP BY
    w1.word
ORDER BY 
    count DESC 
LIMIT 20;

Попробуйте индекс для обоих столбцов:

CREATE INDEX idx_word_user ON words ( word, user_id);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...