есть ли что-то более быстрое, чем " & # 8221; для больших столов?
-
03-07-2019 - |
Вопрос
Вот мой запрос:
select word_id, count(sentence_id)
from sentence_word
group by word_id
having count(sentence_id) > 100;
Слово предложения таблицы содержит 3 поля: слово, идентификатор предложения и идентификатор первичного ключа. Он имеет 350 тыс. Строк. Этот запрос занимает колоссальные 85 секунд, и мне интересно (надеюсь, молиться?), Есть более быстрый способ найти все словаидные слова, содержащие более 100 предложений.
Я попытался убрать часть счетчика select и просто выполнил 'count (1)', но ни один из них не ускорил его.
Буду признателен за любую помощь, которую вы можете оказать. Спасибо!
Решение
имеющий количество (предложений_ид) > 100; р>
Есть проблема с этим ... Либо в таблице есть повторяющиеся пары слово / предложение, либо нет.
Если в нем есть повторяющиеся пары слово / предложение, вы должны использовать этот код, чтобы получить правильный ответ:
HAVING COUNT(DISTINCT Sentence_ID) > 100
<Ч>
Если в таблице нет повторяющихся пар слово / предложение ... тогда вы не должны считать предложение, а просто считать строки.
HAVING COUNT(*) > 100
В этом случае вы можете создать индекс для только word_id для оптимальной производительности.
Другие советы
Если у вас его еще нет, создайте составной индекс по фразе_доставки_слове.
Если этот запрос часто выполняется, а таблица редко обновляется, вы можете сохранить вспомогательную таблицу с идентификаторами слов и соответствующими числами предложений - трудно подумать о какой-либо дальнейшей оптимизации, кроме этого!
Ваш запрос в порядке, но ему нужна помощь (индексы), чтобы получить более быстрые результаты.
У меня нет своих ресурсов (или доступа к SQL), но я постараюсь помочь вам из памяти.
Концептуально, единственный способ ответить на этот запрос - подсчитать все записи с одинаковым идентификатором word_id. Это означает, что движку запросов необходим быстрый способ найти эти записи. Без индекса для word_id единственная вещь, которую может сделать база данных, - это просматривать таблицу по одной записи за раз и продолжать получать итоговые значения для каждого отдельного отдельного слова word_id, которое она находит. Обычно для этого требуется временная таблица, и результаты не могут быть отправлены до тех пор, пока вся таблица не будет отсканирована. Не хорошо.
С индексом word_id он все еще должен проходить таблицу, поэтому вы думаете, это не сильно поможет. Однако механизм SQL теперь может вычислять счетчик для каждого word_id, не дожидаясь конца таблицы: он может отправить строку и счетчик для этого значения word_id (если он передает предложение where
) или отбросить строку (если это не так); это приведет к снижению нагрузки на сервер, возможно, к частичным ответам, и временная таблица больше не нужна. Второй аспект - параллелизм; с индексом word_id SQL может разделить задание на куски и использовать отдельные ядра процессора для параллельного выполнения запроса (в зависимости от возможностей оборудования и существующей рабочей нагрузки).
Этого может быть достаточно, чтобы помочь вашему запросу; но вы должны попытаться увидеть:
CREATE INDEX someindexname ON sentence_word (word_id)
(синтаксис T-SQL; вы не указали, какой продукт SQL вы используете)
Если этого недостаточно (или не помогает), есть два других решения.
Во-первых, SQL позволяет предварительно вычислить COUNT (*) с помощью индексированных представлений и других механизмов. У меня нет деталей под рукой (и я делаю это не часто). Если ваши данные меняются не часто, это даст вам более быстрые результаты, но с затратами на сложность и немного места для хранения.
Кроме того, вы можете рассмотреть возможность сохранения результатов запроса в отдельной таблице. Это целесообразно только в том случае, если данные никогда не изменяются или изменяются по точному графику (скажем, во время обновления данных в 2 часа ночи) или если они меняются очень мало и вы можете жить с неидеальными результатами в течение нескольких часов (вы придется планировать периодическое обновление данных); это моральный эквивалент хранилища данных бедняка.
Лучший способ узнать наверняка, что вам подходит, - это запустить запрос и посмотреть на план запроса с некоторыми индексами-кандидатами, такими как приведенный выше, и без них.
На удивление, есть еще более быстрый способ сделать это на больших наборах данных:
SELECT totals.word_id, totals.num
FROM (SELECT word_id, COUNT(*) AS num FROM sentence_word GROUP BY word_id) AS totals
WHERE num > 1000;