Как ускорить запрос SQL с предложением IN, содержащим 4000 элементов? - PullRequest
0 голосов
/ 19 мая 2018

Я использую python для генерации текста запроса, который затем отправляю на SQL server.Запрос создается в функции, которая принимает список строк, которые затем вставляются в запрос.

Запрос выглядит так:

SELECT * 
FROM DB
WHERE last_word in ('red', 'phone', 'robin')

Проблема в том, что здесь у меня есть только 3 слова: red, phone и robin, но в другом случае использования Iболее 4000 слов и ответ занимает около 2 часов.Как я могу переписать этот запрос, чтобы сделать его более производительным?

Ответы [ 4 ]

0 голосов
/ 19 мая 2018

стратегий оптимизации:

  1. добавить индекс для last_word

    CREATE INDEX ON db(last_word)
    
  2. сохранить слова фильтра в таблице и использоватьWHERE exists (или внутреннее соединение)

    WITH words (word) AS (
    VALUES ('red'), ('phone'), ('robin')
    )
    SELECT * 
    FROM db 
    WHERE EXISTS (SELECT TRUE FROM words WHERE word = last_word)
    

    или

    WITH words (word) AS (
    VALUES ('red'), ('phone'), ('robin')
    )
    SELECT db.* 
    FROM db 
    JOIN words ON db.last_word = words.word
    

    WHERE EXISTS здесь должно быть немного быстрее, чем JOIN

0 голосов
/ 19 мая 2018

Попробуйте сделать что-то вроде этого:

SELECT * 
FROM DB INNER JOIN WORDS_TABLE
ON DB.WORDS = WORDS_TABLE.WORDS;

Вместо * используйте все, что хотите получить.

JOIN в этом случае будет быстрее, чем IN так как вам придется написать еще один внутренний запрос, если вы используете таблицу.

0 голосов
/ 19 мая 2018

Поместите ваши данные во временную таблицу или CTE.Это облегчит добавление новых данных.Точно так же вам придется выполнить внутреннее соединение с исходной таблицей, чтобы убедиться, что вы захватили все.

Надеюсь, это поможет.

0 голосов
/ 19 мая 2018

Сколько строк у вас в «БД»?Есть ли больше слов «last_word», соответствующих 4000 слов в предложении IN, чем нет?Если так, то было бы лучше использовать NOT IN, чтобы исключить вместо include.Кроме того, старайтесь никогда не использовать SELECT *, так как этот подстановочный знак очень бесполезен, лучше явно указать столбцы, которые вы хотите включить в свой запрос.

Вы также можете попытаться поместить 4000 слов для сопоставления в(временная) таблица или CTE, а затем присоединение к ней, поскольку объединения обычно работают лучше, чем большие объемы данных в предложении IN.При этом я все же рекомендую не использовать подстановочный знак в операторе SELECT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...