есть ли что-то более быстрое, чем " & # 8221; для больших столов?

StackOverflow https://stackoverflow.com/questions/818868

Вопрос

Вот мой запрос:

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;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top