Производительность поиска данных - PullRequest
1 голос
/ 07 июня 2019

Используя SSMS или Azure data Studio, я могу вставить полмиллиона строк во временную таблицу за 2 мс, но для извлечения строк, отображаемых на экране из таблицы или временной таблицы, требуется от 13 до 15 секунд.Я не уверен, где искать следующую информацию о том, где была потеряна производительность, поскольку этого не было, и что она возникла несколько месяцев назад.

Это рабочий сервер, который уже несколько месяцев работает в SQL 2017.происходит ли я на клиенте или непосредственно на сервере, но на обычном ПК со стандартными дисками и всего лишь 8 гигабайт оперативной памяти, это в три раза быстрее

SELECT SML.CONTACT_Id
INTO ##slr
FROM dbo.Stage_MailingLists AS SML;

SELECT *
FROM ##slr AS S;

DROP TABLE ##slr;

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 2 ms.
Table 'Stage_MailingLists'. Scan count 9, logical reads 13482, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(521001 rows affected)

(1 row affected)

 SQL Server Execution Times:
   CPU time = 1187 ms,  elapsed time = 365 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

(521001 rows affected)
Table '##slr'. Scan count 1, logical reads 1493, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 329 ms,  elapsed time = 8296 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

Ответы [ 3 ]

1 голос
/ 07 июня 2019

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

Когда вы используете SELECT, для отображения данных эти данные необходимо отправить из экземпляра клиенту; если этот клиент является удаленным хостом, то такие вещи, как скорость / трафик сети, могут быть существенным фактором для больших наборов данных (у вас есть полмиллиона строк здесь, что является приличным количеством для отображения). Прикладная программа также должна интерпретировать эти данные из экземпляра и преобразовать их в отображаемый формат; в SSMS, которые могут преобразовывать его в сетку данных. если вы ограничиваете клиент, то вы также можете замедлить запрос, поскольку данные должны быть загружены в пул памяти приложения и обработаны для отображения.

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

0 голосов
/ 07 июня 2019

Поскольку вы работаете с SQL 2017, вы можете использовать статистику ожидания сеанса для измерения механизма, ожидающего запрос. Например, установить процедуру в Master, как:

use master
go
create or alter procedure sp_exec_with_time_and_wait_stats @sql nvarchar(max)
as
begin

set nocount on;

with q as
(
    select *
    from sys.dm_exec_session_wait_stats
    where session_id = @@spid
    union all
    select @@spid session_id, 'CPU_TIME', 0,cpu wait_time_ms,0,0
    from sysprocesses where spid = @@spid 
)
select *
into #waits
from q 

print ('-------begin batch--------')
print ( @sql )
print ('--------end batch---------')
set statistics io on;
set statistics time on;
exec ( @sql );
set statistics io off;
set statistics time off;

declare c cursor local for
with n as
(
    select *
    from sys.dm_exec_session_wait_stats
    where session_id = @@spid
    union all
    select @@spid session_id, 'CPU_TIME', 0,cpu cpu_time,0,0
    from sysprocesses where spid = @@spid 
)
select n.wait_type, 
       n.waiting_tasks_count - coalesce(p.waiting_tasks_count,0) waiting_tasks_count,
       n.wait_time_ms - coalesce(p.wait_time_ms,0) wait_time_ms,
       case when n.max_wait_time_ms > coalesce(p.max_wait_time_ms,0) then n.max_wait_time_ms else null end max_wait_time,
       n.signal_wait_time_ms - coalesce(p.signal_wait_time_ms,0) signal_wait_time
from n
left join #waits p
  on p.wait_type = n.wait_type
where n.session_id = @@spid
and n.wait_time_ms > coalesce(p.wait_time_ms,0)
order by n.wait_time_ms - coalesce(p.wait_time_ms,0)  desc;

declare @wait_type nvarchar(60),
        @waiting_tasks_count bigint,
        @wait_time_ms bigint,
        @max_wait_time_ms bigint,
        @signal_wait_time_ms bigint
print (
'
SQL Server Wait Times (with CPU):

  wait_type                                                    waiting_tasks_count  wait_time_ms          max_wait_time      signal_wait_time')
print (
'  ------------------------------------------------------------ -------------------- --------------------- ------------------ --------------------')

open c
fetch next from c into @wait_type,  @waiting_tasks_count,  @wait_time_ms,  @max_wait_time_ms,  @signal_wait_time_ms
while @@FETCH_STATUS = 0
begin

  declare @line nvarchar(2000) = N''
  declare @val nvarchar(60) = @wait_type
  declare @len int = 45

  set @line = concat(@line,left(concat(@val, space(@len)),@len))

  set @len = 20
  set @val = str(@waiting_tasks_count)
  set @line = concat(@line,right(concat(space(@len),@val),@len))

  set @val = str(@wait_time_ms)
  set @line = concat(@line,right(concat(space(@len),@val),@len))

  set @val = str(coalesce(@max_wait_time_ms,''))
  set @line = concat(@line,right(concat(space(@len),@val),@len))

  set @val = str(@signal_wait_time_ms)
  set @line = concat(@line,right(concat(space(@len),@val),@len))


  print ('  ' + @line)
  fetch next from c into @wait_type,  @waiting_tasks_count,  @wait_time_ms,  @max_wait_time_ms,  @signal_wait_time_ms
end
close c
deallocate c
print ('')

end

Тогда из вашей базы данных

use AdventureWorksDW2017
go
declare @sql nvarchar(max) = 'select top 1000000 *  into #x from factInternetSales order by 1,2,5;'
exec sp_exec_with_time_and_wait_stats @sql

Который будет печатать ваши статистику ввода-вывода, процессора и ожидания, как:

-------begin batch--------
select top 1000000 *  into #x from factInternetSales order by 1,2,5;
--------end batch---------
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 12 ms.
Table 'FactInternetSales'. Scan count 9, logical reads 1260, physical reads 0, read-ahead reads 1260, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 1057, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 435 ms,  elapsed time = 335 ms.

 SQL Server Execution Times:
   CPU time = 435 ms,  elapsed time = 349 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

SQL Server Wait Times (with CPU):

  wait_type                                                    waiting_tasks_count  wait_time_ms          max_wait_time      signal_wait_time
  ------------------------------------------------------------ -------------------- --------------------- ------------------ --------------------
  LATCH_EX                                                     4879                 572                   0                  69
  CPU_TIME                                                        0                 435                   0                   0
  CXPACKET                                                       22                 331                   0                   0
  PAGEIOLATCH_SH                                                 26                  10                   0                   0
  PAGELATCH_SH                                                   17                   6                   0                   1
  PAGELATCH_UP                                                   74                   6                   0                   1
  LCK_M_S                                                         9                   3                   0                   0
  CXROWSET_SYNC                                                   8                   2                   0                   0
  MEMORY_ALLOCATION_EXT                                         601                   1                   0                   0
  SESSION_WAIT_STATS_CHILDREN                                    11                   1                   0                   1
  LATCH_SH                                                        3                   1                   0                   0
0 голосов
/ 07 июня 2019

Оказывается, у антивируса Sophos было обновление "в ожидании перезапуска", которое вызывало перезапуск сервера и все обратно к ожидаемой базовой линии.

...