выбор 17 миллионов записей в sql server выполняется очень медленно

#sql-server #indexing #sql-execution-plan

Вопрос:

Я пытаюсь выбрать таблицу с 17 миллионами записей . Это занимает около 10 минут . Здесь вы можете ознакомиться с планом выполнения в реальном времени .

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

Вот моя структура таблицы :

 CREATE TABLE [bas].[GatewayReceipt](
    [Id] [INT] IDENTITY(1,1) NOT NULL,
    [CustomerId] [INT] NULL,
    [UserId] [INT] NOT NULL,
    [RefNumber] [NVARCHAR](200) NULL,
    [ResNumber] [NVARCHAR](200) NULL,
    [Price] [DECIMAL](18, 5) NOT NULL,
    [GatewayChannelId] [INT] NOT NULL,
    [StatusId] [INT] NOT NULL,
    [EntryDate] [DATETIME] NOT NULL,
    [ModifyDate] [DATETIME] NULL,
    [RowVersion] [TIMESTAMP] NOT NULL,
 CONSTRAINT [PK_Bas_GatewayReceipt] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [FG_ATS]
) ON [FG_ATS]
GO
 

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

Как примечание, у меня есть 3 некластеризованных индекса на
1:Идентификатор клиента
2:Идентификатор клиента и идентификатор пользователя
3:gatewaychannelId

мой вопрос :

 select * from  bas.GatewayReceipt where  gatewaychannelId in (1,2,3)
 

почему мой запрос работает медленно ?

Комментарии:

1. И в чем заключается ваш вопрос? ВЫБЕРИТЕ * извне, ГДЕ нельзя использовать индексы

2. @Sergey извините, что я изменил запрос . у меня есть пункт where в gatewaychannelid

3. @Сергей в качестве основного вопроса, почему запрос select без where должен быть таким медленным ?

4. Вы серьезно все, кажется, игнорируете эту вещь. Не имеет значения, есть индекс или нет — даже без индекса сканирование 17 миллионов строк не должно ЗАНИМАТЬ 10 минут на современном оборудовании. Работает ли hit на 5-летнем телефоне, 20-летнем компьютере? ОЧЕНЬ, ОЧЕНЬ, ОЧЕНЬ мало ОПЕРАТИВНОЙ ПАМЯТИ? 10 минут-это возмутительно, индекс это или нет.

5. Что конкретно означает «Это занимает около 10 минут»? Проводите ли вы измерения с точки зрения применения? Насколько медленно приложение извлекает набор результатов и что-то с ним делает? И что это приложение делает с набором результатов? Насколько медленное сетевое соединение между сервером и приложением? Даже если план выполнения может быть улучшен, вы можете не увидеть значительного улучшения, если проблема заключается в потреблении набора результатов.

Ответ №1:

Результаты медленные, в основном из-за времени, необходимого клиентскому приложению (SSMS) для отображения большого результата в 17 миллионов строк.

А именно, SSMS требуется около 70 секунд, чтобы отобразить результат 10 миллионов строк этого запроса на моем компьютере в сетке, и диспетчер задач показывает, что SSMS полностью привязан к процессору во время выполнения:

 WITH 
     t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
    ,t1k AS (SELECT 0 AS n FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
    ,t10m AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t1k AS a CROSS JOIN t1k AS b CROSS JOIN t10 AS c)
SELECT num
FROM t10m;
 

Повторяя один и тот же запрос без полной визуализации (Запрос—>Параметры—>>Сетка—>>>Удаление результатов после выполнения), для извлечения строк требуется всего 12 секунд, но не для их отображения.

Учтите, что время сквозного ответа является мерой как клиентского, так и серверного времени.

Ответ №2:

С таблицы нужно INDEX начинать gatewaychannelId .

Однако, если большинство или все строки в таблице имеют значения 1, 2 или 3, индекс фактически замедлит выполнение запроса. В этом случае быстрее просто прочитать таблицу, отфильтровав несколько строк, которые не применяются.