SQL Server медленный выбор из большой таблицы

git cherry branch [newbranch]

делает точно, что Вы спрашиваете, когда Вы находитесь в эти master ответвление.

я также очень люблю:

git diff --name-status branch [newbranch]

, Который не является точно, что Вы спрашиваете, но все еще очень полезно в том же контексте.

9
задан marc_s 2 December 2009 в 19:41
поделиться

9 ответов

Скорее всего, вы захотите создать составной индекс для этого типа запроса - когда запрос выполняется медленно, он, скорее всего, будет сканировать индекс в столбце CreatedAt и выполнять остаточный фильтр. для значения SourceUserId, тогда как на самом деле вы хотите перейти непосредственно ко всем записям для данного SourceUserId, упорядоченного должным образом - для этого вам нужно создать составной индекс в первую очередь для SourceUserId (выполнение проверки равенства) и во-вторых, CreateAt (чтобы сохранить порядок в пределах заданного значения SourceUserId). Вы можете также попробовать добавить TypeId, в зависимости от избирательности этого столбца.

Итак, 2, которые, скорее всего, дадут наилучшую воспроизводимость (попробуйте их и сравните), будут:

  1. Индекс on (SourceUserId, CreatedAt)
  2. Индекс на (SourceUserId, TypeId, CreatedAt)

Как всегда, есть также много других соображений, которые следует учитывать при определении того, как / что / где индексировать, поскольку Ремус обсуждает в отдельном ответе, одно большое соображение касается запроса и сохранения поисков. Кроме того, вам необходимо учитывать объемы записи, возможное влияние фрагментации (если таковое имеется) , одиночный поиск по сравнению с большим последовательным сканированием и т. Д. И т. Д.

15
ответ дан 4 December 2019 в 07:35
поделиться

У меня есть индексы для каждого столбца, кроме MetaId

Непокрывающие индексы, скорее всего, достигнут «переломной точки» , и запрос вернется к просмотру таблицы. Простое добавление индекса в каждый столбец, потому что он используется в предложении where, не означает хороший дизайн индекса. Чтобы взять ваш запрос, например, хороший индекс 100% покрытия будет:

INDEX ON (SourceUserId , CreatedAt) INCLUDE (TypeId, SrcMemberId, DstMemberId)

Следующий индекс также полезен, хотя он все еще будет вызывать поиск:

INDEX ON (SourceUserId , CreatedAt) INCLUDE (TypeId)

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

INDEX ON (SourceUserId , CreatedAt)

Но отдельный индекс для SourceUSerId и один для CreatedAt в основном бесполезны для вашего запроса.

См. ] Основы разработки индексов .

6
ответ дан 4 December 2019 в 07:35
поделиться

last const:

  • Функция не изменяет частные значения класса

один после последнего const:

  • Это постоянный указатель (т.е. место он указывает на константу)

second const:

  • Функция возвращает const char (т. е. содержимое char является постоянным)

Первое:

  • Понятия не имею?

Итак, чтобы завершить: Функция возвращает постоянный указатель (всегда одно и то же местоположение) на постоянный символ (всегда одно и то же содержимое), и функция не изменяет состояние класса.

5
ответ дан 4 December 2019 в 07:35
поделиться

Я бы порекомендовал получить данные в 2 отдельных таблицах var

INSERT INTO @Table1
SELECT * FROM Events WITH (NOLOCK)
WHERE SourceUserId = '15b534b17-5a5a-415a-9fc0-7565199c3461'
AND 
(
 TypeId IN (2, 3, 4)
)
INSERT INTO @Table2
SELECT * FROM Events WITH (NOLOCK)
WHERE SourceUserId = '15b534b17-5a5a-415a-9fc0-7565199c3461'
AND 
(
 (TypeId = 60 AND SrcMemberId != DstMemberId)
)

, а затем применить unoin из выбранных, упорядоченных и верхних. Ограничьте объем данных с самого начала.

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

Я предлагаю использовать UNION:

SELECT TOP 100 x.*
  FROM (SELECT a.*
          FROM EVENTS a
         WHERE a.typeid IN (2, 3, 4)
        UNION ALL
        SELECT b.*
          FROM EVENTS b
         WHERE b.typeid = 60 
           AND b.srcmemberid != b.dstmemberid) x
 WHERE x.sourceuserid = '15b534b17-5a5a-415a-9fc0-7565199c3461'
1
ответ дан 4 December 2019 в 07:35
поделиться

Мы достигли небольшого выигрыша, перейдя к клавише BIGINT IDENTITY для нашей таблицы событий; используя его как кластерный первичный ключ, мы можем обмануть и использовать его для упорядочивания даты.

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

Я бы удостоверился, что CreatedAt правильно проиндексирован

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

вы можете разделить запрос на две части с помощью UNION, чтобы избежать OR (что может привести к тому, что ваш индекс не будет использоваться), что-то вроде

   SElect * FROM(
 SELECT TOP 100 * FROM Events WITH (NOLOCK)
WHERE SourceUserId = '15b534b17-5a5a-415a-9fc0-7565199c3461'
AND TypeId IN (2, 3, 4)
UNION  SELECT TOP 100 * FROM Events WITH (NOLOCK)
WHERE SourceUserId = '15b534b17-5a5a-415a-9fc0-7565199c3461' 
 AND TypeId = 60 AND SrcMemberId != DstMemberId
)
ORDER BY CreatedAt DESC

Также проверьте, что индексы uniqueidentifier не КЛАСТЕРИРОВАНЫ.

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

Если каждый день добавляется 100 000 записей, вам следует проверить фрагментацию индекса. И соответственно перестроить или реорганизовать его. Больше информации : SQLauthority

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