Nano Hash - криптовалюты, майнинг, программирование

Почему этот запрос выполняется так медленно?

Этот запрос выполняется очень быстро (‹100 мс):

SELECT TOP (10) 
    [Extent2].[CompanyId] AS [CompanyId]
    ,[Extent1].[Id] AS [Id]
    ,[Extent1].[Status] AS [Status]
FROM [dbo].[SplittedSms] AS [Extent1]
INNER JOIN [dbo].[Sms] AS [Extent2]
    ON [Extent1].[SmsId] = [Extent2].[Id]
WHERE [Extent2].[CompanyId] = 4563 
    AND ([Extent1].[NotifiedToClient] IS NULL)

Если я добавлю только временной фильтр, это займет слишком много времени (22 секунды!):

SELECT TOP (10) 
    [Extent2].[CompanyId] AS [CompanyId]
    ,[Extent1].[Id] AS [Id]
    ,[Extent1].[Status] AS [Status]
FROM [dbo].[SplittedSms] AS [Extent1]
INNER JOIN [dbo].[Sms] AS [Extent2]
    ON [Extent1].[SmsId] = [Extent2].[Id]
WHERE [Extent2].Time > '2015-04-10'
    AND [Extent2].[CompanyId] = 4563 
    AND ([Extent1].[NotifiedToClient] IS NULL)

Я попытался добавить индекс в столбец [Time] таблицы Sms, но оптимизатор, похоже, не использует индекс. Пробовал использовать With (index (Ix_Sms_Time)); но, к моему удивлению, это занимает еще больше времени (29 секунд!).

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

План выполнения одинаков для обоих запросов. Упомянутые здесь таблицы содержат от 5 млн до 8 млн строк (индексы фрагментированы на ‹ 1%, а статистика обновляется). Я использую MS SQL Server 2008R2 на 16-ядерном компьютере с 32 ГБ памяти Windows 2008 R2)


  • Попробуйте добавить столбец ORDER BY ASC или DESC TIME и проверьте. Он должен работать быстрее. 15.04.2015
  • Во-первых, без ORDER BY строки, возвращаемые запросом TOP, не являются детерминированными. Лучше всего указать ORDER BY с TOP. Чтобы повысить производительность второго запроса, попробуйте составной некластеризованный индекс для CompanyID и Time. Это позволит избежать касания строк ‹= '2015-04-10'. 15.04.2015
  • Пробовал Order By [Time]; хуже, 29 секунд! 15.04.2015
  • Можете выложить скрипты создания таблиц? Вместе с определением индекса 15.04.2015
  • не могли бы вы опубликовать фактический план выполнения где-нибудь, чтобы мы могли получить к нему доступ и увидеть фактическую матрицу? 15.04.2015

Ответы:


1

Помогает ли это, когда вы заставляете временной фильтр срабатывать только после запуска клиентского фильтра?

FI, как в этом примере:

;WITH ClientData AS (   
    SELECT 
         [E2].[CompanyId]
        ,[E2].[Time]
        ,[E1].[Id]
        ,[E1].[Status]
    FROM [dbo].[SplittedSms] AS [E1]
    INNER JOIN [dbo].[Sms] AS [E2]
        ON [E1].[SmsId] = [E2].[Id]
    WHERE  [E2].[CompanyId] = 4563 
      AND ([E1].[NotifiedToClient] IS NULL)
)
SELECT TOP 10
     [CompanyId]    
    ,[Id]
    ,[Status]
FROM ClientData
WHERE [Time] > '2015-04-10'
15.04.2015

2

Создайте индекс для Sms со следующими Index Key Columns (в этом порядке):

  1. Идентификатор компании
  2. Время

Вам может понадобиться или не понадобиться добавлять Id в качестве Included Column.

15.04.2015

3

Какой тип данных у вашего столбца Time? Если это дата и время, попробуйте преобразовать «2015-04-10» в эквивалентный тип данных, чтобы он мог использовать индекс.

Declare @test datetime
Set @test='2015-04-10'

Затем измените свое условие:

[Extent2].Time > @test    

Сервер sql неявно выполняет приведение к соответствующему типу данных, если существует несоответствие типа данных. И любая функция или операция приведения запрещают использование индексов.

15.04.2015
  • Изменение даты в переменной заставит оптимизатор оптимизировать предложение для неизвестного значения (если это не хранимая процедура), а в случае полей даты и времени и даты, близкой к текущему дню, это может ухудшить ситуацию. Имея дату и время в правильном формате, например. «20150410» должно быть в порядке. 15.04.2015

  • 4

    Я нахожусь на том же пути, что и @JonTirjan, индекс только с временем приводит к множеству ключевых запросов, поэтому вы должны попробовать, по крайней мере, следующее:

    create index xxx on Sms (Time, CompanyId) include (Id)
    

    or

    create index xxx on Sms (CompanyId, Time) include (Id)
    

    Если Id — это ваш кластеризованный индекс, то он не нужен в предложении include. Если значительная часть ваших данных относится к CompanyID 4563, может быть нормально, чтобы он также был включен в столбец.

    Проценты, которые вы видите в фактическом плане, являются просто оценками, основанными на предположениях о количестве строк, поэтому они иногда совершенно неверны. Глядя на фактическое количество строк/выполнений + вывод статистики ввода-вывода, вы должны понять, что на самом деле происходит.

    15.04.2015

    5

    На ум приходят две вещи:

    1. При добавлении дополнительного ограничения базе данных будет «сложнее» найти первые 10 элементов, соответствующих вашим ограничениям. Найти первые 10 строк, скажем, из 10 000 элементов (из общего числа в 1 миллион) проще, чем найти первые 10 строк, возможно, из 100 элементов (в общей сложности из 1 миллиона).
    2. Индекс не используется, вероятно, потому, что индекс создается в столбце даты и времени, что не очень эффективно, если вы также сохраняете в них время. Возможно, вы захотите создать кластеризованный индекс в столбце [time] (но тогда вам придется удалить кластеризованный индекс, который теперь находится в столбце [CompanyId], или вы можете создать вычисляемый столбец, в котором хранится дата-часть [ время], создайте индекс для этого вычисляемого столбца и отфильтруйте этот столбец.
    15.04.2015

    6

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

    План выполнения сейчас:

    введите здесь описание изображения

    Спасибо всем за усилия.

    16.04.2015
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

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

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..