Запрос большой таблицы в sql server 2008

У нас есть таблица с 250 миллионами записей (уникальное 15-значное число. Столбец кластеризованного уникального индекса), которые будут запрашиваться не менее чем от 0,7 до 0,9 миллиона запросов в среднем в день.

У нас есть несколько приложений, обращающихся к этой таблице. Каждое приложение будет пытаться сравнить 500 000 данных с 260 миллионами записей.

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

Как мы можем улучшить производительность запроса? Как мы можем поддерживать эту таблицу? Разделить это? Среда: Win 2K8R2, SQL 2K8R2, ОЗУ 64 ГБ, 8 ядер с двумя процессорами


person Kishore    schedule 18.02.2013    source источник
comment
Посмотрите на план выполнения запроса для подсказок.   -  person leppie    schedule 18.02.2013
comment
Он быстро растет - он увеличился на 10 миллионов строк между первым и вторым абзацами! :-)   -  person Damien_The_Unbeliever    schedule 18.02.2013
comment
@Damien_The_Unbeliever LOL!   -  person Mr Moose    schedule 18.02.2013
comment
Также не забудьте разделить большое обновление на более мелкие пакеты, чтобы предотвратить эскалацию блокировки. Подробности на msdn.microsoft.com   -  person Dalex    schedule 18.02.2013


Ответы (2)


Если несколько приложений только пытаются сравнить данные, я считаю, что они не записываются в таблицу, записи кеширования также должны помочь. Также существует метод, называемый шардингом, который, к сожалению, SQL-сервер не поддерживает. Но на codeplex есть библиотека, которая предоставляет такую ​​возможность для SQL Server. Он в основном пытается сбалансировать нагрузку на базы данных.

Я не тестировал это, но стоит попробовать. Если хотите, можете посмотреть здесь http://enzosqlshard.codeplex.com/.

person Salman    schedule 18.02.2013

1. Используйте временные таблицы

Создайте временную таблицу для подмножества (строк и столбцов) интересующих вас данных. Временная таблица должна быть намного меньше исходной исходной таблицы и ее можно легко индексировать (при необходимости).

Для создания временной таблицы вы можете использовать код (не проверенный), например:

-- copy records from last month to temporary table
INSERT INTO
   #my_temporary_table
SELECT
    *
FROM
    er101_acct_order_dtl WITH (NOLOCK)
WHERE 
    er101_upd_date_iso > DATEADD(month, -1, GETDATE())

-- run other queries on temporary table (which can be indexed)
SELECT TOP 100
    * 
FROM 
    #my_temporary_table 
ORDER BY 
    er101_upd_date_iso DESC

Плюсы:

Легко сделать для любого набора данных. Легко управлять - это временно и это таблица. Не влияет на общую производительность системы, например на просмотр. Временную таблицу можно индексировать. Минусы:

Это моментальный снимок данных, но, вероятно, этого достаточно для специальных запросов.

2. Создайте представления.

Аналогично предыдущему, но вместо временных таблиц создавайте представления.

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

Плюсы:

Легко сделать. Это актуально с исходными данными. Минусы:

Возможно только для определенного набора данных. Может быть неэффективным для больших таблиц с высокой скоростью обновления. Не так-то просто управлять. Может повлиять на общую производительность системы. Выбор всех столбцов Запуск звездного запроса (SELECT * FROM) для большой таблицы - это нехорошо ...

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

Я бы попытался заменить * на имена столбцов, которые вам действительно нужны.

Или, если вам нужны все столбцы, попробуйте переписать запрос примерно так:

;WITH recs AS (
    SELECT TOP 100 
        id as rec_id -- select primary key only
    FROM 
        er101_acct_order_dtl 
    ORDER BY 
        er101_upd_date_iso DESC
)
SELECT
    *
FROM
    er101_acct_order_dtl
WHERE 
    id = rec.rec_id
ORDER BY 
    er101_upd_date_iso DESC 

Грязные чтения

Последнее, что может ускорить запрос, - это разрешить грязное чтение с табличной подсказкой WITH (NOLOCK).

Вместо подсказки вы можете установить уровень изоляции транзакции на чтение без фиксации:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
person Community    schedule 18.02.2013
comment
Предлагать изменение уровня изоляции транзакции без знания схемы базы данных и запросов чтения / записи - не лучшая идея. NOLOCK может предоставлять грязные данные. Пожалуйста, посмотрите здесь stackoverflow.com - person Dalex; 18.02.2013