как структурировать индекс для группы в SQL-сервере

Лично мой дб разработки для проекта, я продолжаю работать, прямо сейчас является довольно большим, таким образом, я использую dmigrations для создания сценариев миграции дб для изменения дб (вместо того, чтобы вытереть дб каждый раз как, я сделал в начале).

Редактирование: На самом деле я использую Юг теперь :-)

7
задан ekad 27 January 2017 в 09:06
поделиться

6 ответов

Try to tell SQL Server to use the index:

...
FROM [fctWMAUA] (NOLOCK, INDEX(IX)) AS [t0]
...

Make sure the statistics for the table are up to date:

UPDATE STATISTICS [fctWMAUA]

For better answers, turn on the showplan for both queries:

SET SHOWPLAN_TEXT ON

and add the results to your question.

You can also write the query without a GROUP BY. For example, you can use an exclusive LEFT JOIN excluding rows with older dates:

select cur.SourceSystemKey, cur.date
from fctWMAUA cur
left join fctWMAUA next
    on next.SourceSystemKey = next.SourceSystemKey
    and next.date > cur.date
where next.SourceSystemKey is null
and cur.SourceSystemKey in (1,2,3,4,5,6,7,8,9)

This can be surprisingly fast, but I don't think it could beat the UNION.

1
ответ дан 7 December 2019 в 07:46
поделиться
 WHERE SourceSystemKey = 3
 GROUP BY [t0].[SourceSystemKey]

You don't need to group by a fixed field.

Any way I prefer the first sentence. May be I will replace the

 WHERE SourceSystemKey in (1,2,3,4,5,6,7,8,9)

for something like

 WHERE SourceSystemKey BETWEEN 1 AND 9

or

 WHERE SourceSystemKey >= 1 AND SourceSystemKey <= 9

if SourceSystemKey is an integer. But I don't think it will cause a big change.

What I will test first is rebuild statistics and rebuild all indexes for the table and wait some time. Rebuilding is not instant, it will depend on how busy is the server but this sentence is well structured for the index be used by the optimizer.

Regards.

0
ответ дан 7 December 2019 в 07:46
поделиться

Вы пробовали создать еще один индекс только для столбца SourceSystemKey? Большое количество логических чтений, когда вы используете этот столбец в своем предложении where, заставляет меня думать, что он выполняет сканирование индекса / таблицы. Не могли бы вы запустить план выполнения и посмотреть, так ли это? В плане выполнения также может быть предложен индекс.

0
ответ дан 7 December 2019 в 07:46
поделиться

Трудно сказать, не глядя на план выполнения, однако вы можете попробовать следующее:

SELECT * FROM
(
    SELECT MAX(t0.AsAtDateKey) AS [Date], t0.SourceSystemKey AS SourceSystem
    FROM fctWMAUA (NOLOCK) AS t0
    GROUP BY t0.SourceSystemKey
)
WHERE SourceSystem in (1,2,3,4,5,6,7,8,9)

Сложно сказать, не глядя на план выполнения, но я думаю, что происходит заключается в том, что SQL-сервер недостаточно умен, чтобы понять, что указанное предложение WHERE отфильтровывает группы и не оказывает никакого влияния на записи, включенные для каждой группы. Как только SQL-сервер осознает это, он сможет свободно использовать еще несколько интеллектуальных поисков по индексу для определения максимальных значений (что и происходит во втором запросе)

Это просто теория, но, возможно, стоит попробовать.

2
ответ дан 7 December 2019 в 07:46
поделиться

Используйте HAVING вместо WHERE, чтобы фильтрация происходила ПОСЛЕ того, как произошло группирование:

SELECT MAX(AsAtDateKey) AS [Date], SourceSystemKey AS SourceSystem
FROM fctWMAUA (NOLOCK)
GROUP BY SourceSystemKey
HAVING SourceSystemKey in (1,2,3,4,5,6,7,8,9)

Я также не особо обращаю внимание на предложение IN, особенно когда его можно заменить на «<10» или «Между 1 и 9», которые лучше используются в отсортированных индексах.

1
ответ дан 7 December 2019 в 07:46
поделиться

Я обнаружил, что лучшее решение - следующее. Он имитирует объединенную версию запроса и выполняется очень быстро.

40 логических чтений и время выполнения 3 мс.

SELECT [t3].[value]
FROM [dimSourceSystem] AS [t0]
OUTER APPLY (
    SELECT MAX([t2].[value]) AS [value]
    FROM (
        SELECT [t1].[AsAtDateKey] AS [value], [t1].[SourceSystemKey]
        FROM [fctWMAUA] AS [t1]
        ) AS [t2]
    WHERE [t2].[SourceSystemKey] = ([t0].[SourceSystemKey])
    ) AS [t3]
3
ответ дан 7 December 2019 в 07:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: