2009-11-05 2 views
1

ASP.NET и SQL Server, имеют SQLs для выбора подмножества строк, мне нужно количество * частоВыполнение SQL Count *

Конечно, я могу есть выбор COUNT (*) для каждого из этих SQLs в каждом кругообороте, но скоро он станет слишком медленным.

-Как вы делаете это действительно быстро?

ответ

1

У вас возникла проблема, которая не может быть решена путем добавления другого индекса в таблицу? Операции COUNT (*) обычно равны O (log n) в терминах полных строк и O (n) в терминах возвращенных строк.

Edit: То, что я имею в виду (в случае, если я неправильно понял ваш вопрос)

Учитывая эту структуру:

CREATE TABLE emails (
    id INT, 
    .... OTHER FIELDS 
) 

CREATE TABLE filters (
    filter_id int, 
    filter_expression nvarchar(max) -- Or whatever... 
) 

Создать таблицу

CREATE TABLE email_filter_matches (
    filter int, 
    email int, 
    CONSTRAINT pk_email_filter_matches PRIMARY KEY(filter, email) 
) 

Данные в этой таблице будет иметь обновляться каждый раз при обновлении фильтра или при получении нового сообщения.

Затем запрос типа

SELECT COUNT(*) FROM email_filter_matches WHERE filter = @filter_id 

должно быть O (§ п) в отношении общего количества фильтров совпадений, и О (п) в отношении числа совпадений для этого конкретного фильтра. Так как ваш пример показывает только небольшое количество совпадений (что кажется реалистичным, когда дело касается фильтров электронной почты), это вполне может быть в порядке.

Если вы действительно хотите, конечно, вы могли бы создать триггер в таблице email_filter_matches, чтобы синхронизировать кешированное значение в таблице фильтров, но это может быть сделано в тот день, когда вы столкнулись с проблемами производительности. Нет ничего странного в том, чтобы правильно использовать подобные вещи в параллельных системах.

+0

Как я уже говорил, фильтры определяются пользователями, поэтому предложения непредсказуемы и могут быть сложными и трудоемкими для сервера. Существуют также настраиваемые поля, которые делают предложение более непредсказуемым. И если вы сделаете пару отсчетов *, где ... в каждом раунде с большим количеством строк это вызовет проблемы с производительностью независимо от индексов и т. Д. Индекс будет делать, если запрос был предсказуемым или хотя бы простым – 2009-11-05 10:36:24

0

Вот несколько идей для ускорения COUNT (*) на уровне данных:

  1. Keep таблицу и кластерный индекс как можно более узким, так что больше строк подходят на странице
  2. Keep критерии фильтрации максимально просты, поэтому подсчет идет быстро
  3. Сделайте все возможное, чтобы убедиться, что строки, которые будут считаться, находятся в памяти, прежде чем вы начнете считать их (возможно, используя предварительное кэширование).
  4. Убедитесь, что ваш аппаратное обеспечение оптимизировано (достаточное количество оперативной памяти, достаточно быстрые диски и т. д.)
  5. Рассмотрим результаты кэширования в отдельных таблицах

В качестве альтернативы, если только фильтры часто меняются и не сами данные, вы можете подумать о создании куба с использованием Analysis Services и запускать запросы к этим.