Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4256
читаю статъю

http://msmvps.com/blogs/gladchenko/archive/2009/09/28/1727878.aspx

непонятно как автор вставляет данные

имею таблицу:

IF EXISTS (SELECT * FROM sysobjects WHERE NAME = 'Scenario' AND xtype = 'U')
	DROP TABLE dbo.Scenario
GO 
create table Scenario
(
i1 int not null, 
i2 int not null, 
i3 int not null, 
i4 int not null, 
f1 float,f2 float,f3 float,f4 float,f5 float,f6 float,f7 float,f8 float,f9 float,f10 float
)

IF EXISTS (SELECT * FROM sysobjects WHERE NAME = 'PK_Scenario' AND xtype = 'PK')
	ALTER TABLE Scenario DROP CONSTRAINT [PK_Scenario]
GO 
ALTER TABLE Scenario ADD CONSTRAINT [PK_Scenario] PRIMARY KEY CLUSTERED 
(
	i1 ASC,
	i2 ASC,
	i3 ASC
)
GO


написал утилиту заполняюшую ето таблицу тестовыми данными.

Сначала идет вставка миллиона записей

    
 m_pIRowsetFastLoad->InsertRow( m_hAccessor, m_pData );
хSRC]

потом 
[SRC C++] m_pIRowsetFastLoad->Commit( cmd );


вставка длится 7 секунд и сабмит 50 s (making index I guess).

пробовал запускатъ оба запроса из статъи - никаких PAGELATCH не наблюдалосъ.

тестировал на вставке 3.4 миллиарда записей (1Tb).
9 фев 12, 01:55    [12059076]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Crimean
Member

Откуда:
Сообщений: 13147
потоков сколько пускал?
9 фев 12, 02:13    [12059082]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4256
Crimean
потоков сколько пускал?


один поток

2 потока в 4 раза медленее в итоге - но оба запроса тоже ничего не возврашают
9 фев 12, 02:53    [12059095]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Lepsik,

Так может дисковая не справляется? Ожидания какие при вставке?
9 фев 12, 09:49    [12059459]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
И монотонно ли ключ возрастает, собственно?
9 фев 12, 09:50    [12059479]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Crimean
Member

Откуда:
Сообщений: 13147
там по-моему изначально речь про многопоточную работу. иначе все разговоры про число ядер не имеют смысла
9 фев 12, 11:48    [12060536]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5116
Цитата: "...Всегда, когда несколько потоков получают синхронный доступ к одному и тому же ресурсу, может проявиться описанная выше проблема..."
9 фев 12, 11:52    [12060593]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4256
Дедушка
Цитата: "...Всегда, когда несколько потоков получают синхронный доступ к одному и тому же ресурсу, может проявиться описанная выше проблема..."


осталосъ определится что значит синхронный и кто синхронизирует.

запускал 6 потоков на 8 корной машине.

да, индексы растут монотонно.
9 фев 12, 18:45    [12065273]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Александр Гладченко
Member

Откуда:
Сообщений: 10802
Блог
Lepsik
...осталосъ определится что значит синхронный и кто синхронизирует...


Речь о том, какое API операционки использует для доступа к устройству долговременного хранения SQL Server.
10 фев 12, 11:24    [12067876]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4256
если вставляю через .NET

The second query failing:

Msg 245, Level 16, State 1, Line 2
Conversion failed when converting the nvarchar value ':1:2035017' to data type int.
11 фев 12, 02:03    [12073354]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Александр Гладченко
Member

Откуда:
Сообщений: 10802
Блог
Lepsik
если вставляю через .NET

The second query failing:

Msg 245, Level 16, State 1, Line 2
Conversion failed when converting the nvarchar value ':1:2035017' to data type int.


А что Вам не понятно в тексте этой ошибки?
13 фев 12, 10:40    [12079868]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Crimean
Member

Откуда:
Сообщений: 13147
меня больше другое волнует - при таких "обходах" оптимизатор перестанет считать поле ИД уникальным
а это ой как аукнется для сложных запросов
впрочем, обход есть обернуть таблицу представлением, как-то так:

create view v as select * from a where HashId = cast( abs( Id ) % 4 as tinyint )


только вот после оверхед все равно будет сильно выше, чем указано в статье
15 фев 12, 16:45    [12097232]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4256
Александр Гладченко
Lepsik
если вставляю через .NET

The second query failing:

Msg 245, Level 16, State 1, Line 2
Conversion failed when converting the nvarchar value ':1:2035017' to data type int.


А что Вам не понятно в тексте этой ошибки?


1. мне все понятно

2. в том что статья изобилует ошибками со скриптами.
15 фев 12, 18:28    [12098326]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Александр Гладченко
Member

Откуда:
Сообщений: 10802
Блог
Lepsik,

Вы можете выразиться яснее?
Когда я переводил статью, проверял работоспособность всех сценариев, да и сейчас, после копипаста в SSMS, всё отрабатывает без ошибки конвертации...

Сообщение было отредактировано: 15 фев 12, 18:38
15 фев 12, 18:37    [12098402]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
squid
Member

Откуда: LA
Сообщений: 590
Lepsik
Дедушка
Цитата: "...Всегда, когда несколько потоков получают синхронный доступ к одному и тому же ресурсу, может проявиться описанная выше проблема..."


осталосъ определится что значит синхронный и кто синхронизирует.

запускал 6 потоков на 8 корной машине.

да, индексы растут монотонно.


Если пытатся воспроизвести, то и это условие тоже

Рабочая нагрузка представляла собой хорошо распараллеленные операции вставки, направляемые в несколько больших таблиц.
Рабочая нагрузка масштабировалась до 128 процессорных ядер



Теоретически статья хорошая, дело пишут - надо проверить.

ЗЫ статистику по вейтам Вы всеже приведите, возможно у Вас узкое место не паралельный достув к странице индекса.

Кстати, при вставке в 2008R2 дабы нивелировать IO можно использовать minimally logged insert
16 фев 12, 01:39    [12100140]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
squid
Member

Откуда: LA
Сообщений: 590
Александр Гладченко,

есть ошибки,

видимо небыло вейтов, поэтому конверт не происходил.

откорректировал
SELECT wt.session_id, wt.wait_type, wt.wait_duration_ms
, s.name AS schema_name
, o.name AS object_name
, i.name AS index_name
FROM sys.dm_os_buffer_descriptors bd
JOIN (
SELECT *
  , CHARINDEX(':', resource_description) AS file_index
  , CHARINDEX(':', resource_description
  , [b]1 +[/b] CHARINDEX(':', resource_description)) AS page_index
  , resource_description AS rd
FROM sys.dm_os_waiting_tasks wt
WHERE wait_type LIKE 'PAGELATCH%'
) AS wt
ON bd.database_id = SUBSTRING(wt.rd, 0, wt.file_index)
AND bd.file_id    = SUBSTRING(wt.rd, [b]1 +[/b] wt.file_index, [b]-1 +[/b]wt.page_index - wt.file_index)
AND bd.page_id    = SUBSTRING(wt.rd, [b]1 +[/b] wt.page_index, LEN(wt.rd))
JOIN sys.allocation_units au ON bd.allocation_unit_id = au.allocation_unit_id
JOIN sys.partitions p ON au.container_id = p.partition_id
JOIN sys.indexes i ON p.index_id = i.index_id AND p.object_id = i.object_id
JOIN sys.objects o ON i.object_id = o.object_id
JOIN sys.schemas s ON o.schema_id = s.schema_id 


проверка
Select
SUBSTRING(wt.rd, 0, wt.file_index),
SUBSTRING(wt.rd, 1 + wt.file_index, -1 +wt.page_index - wt.file_index),
SUBSTRING(wt.rd, 1 + wt.page_index, LEN(wt.rd))
From
(
SELECT *
  , CHARINDEX(':', resource_description) AS file_index
  , CHARINDEX(':', resource_description
  , 1 + CHARINDEX(':', resource_description)) AS page_index
  , resource_description AS rd
FROM (Select '1:11:1555' as resource_description) as wt
) AS wt
16 фев 12, 02:12    [12100162]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
squid
Member

Откуда: LA
Сообщений: 590
Сорри выделение болдом в SRC\TSQL не работает
--if @@ROWCOUNT != 0 
SELECT wt.session_id, wt.wait_type, wt.wait_duration_ms
, s.name AS schema_name
, o.name AS object_name
, i.name AS index_name
FROM sys.dm_os_buffer_descriptors bd
JOIN (
SELECT *
  , CHARINDEX(':', resource_description) AS file_index
  , CHARINDEX(':', resource_description
  , 1 + CHARINDEX(':', resource_description)) AS page_index
  , resource_description AS rd
FROM sys.dm_os_waiting_tasks wt
WHERE wait_type LIKE 'PAGELATCH%'
) AS wt
ON bd.database_id = SUBSTRING(wt.rd, 0, wt.file_index)
AND bd.file_id    = SUBSTRING(wt.rd, 1 + wt.file_index, -1 +wt.page_index - wt.file_index)
AND bd.page_id    = SUBSTRING(wt.rd, 1 + wt.page_index, LEN(wt.rd))
JOIN sys.allocation_units au ON bd.allocation_unit_id = au.allocation_unit_id
JOIN sys.partitions p ON au.container_id = p.partition_id
JOIN sys.indexes i ON p.index_id = i.index_id AND p.object_id = i.object_id
JOIN sys.objects o ON i.object_id = o.object_id
JOIN sys.schemas s ON o.schema_id = s.schema_id 
16 фев 12, 02:13    [12100163]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4256
Александр Гладченко
Lepsik,

Вы можете выразиться яснее?
Когда я переводил статью, проверял работоспособность всех сценариев, да и сейчас, после копипаста в SSMS, всё отрабатывает без ошибки конвертации...


одну ошибку я приводил - вот вторая:

CREATE UNIQUE CLUSTERED INDEX CIX_Hash
ON HeavyInsert_Hash (ID, HashID) ON pshash(HashID)


Msg 7726, Level 16, State 1, Line 1
Partition column 'HashID' has data type tinyint which is different from the partition function 'pfhash' parameter data type int.
16 фев 12, 06:01    [12100253]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Lepsik
Member

Откуда: glubinka
Сообщений: 4256
Crimean
меня больше другое волнует - при таких "обходах" оптимизатор перестанет считать поле ИД уникальным
а это ой как аукнется для сложных запросов


меня больше другое не нравится - не могу иметь второй уникальный индекс.

Когда у меня большой составной ключ - я делаю одно поле с PK для просты жизни в запросах, теперь борюсь с латчами и придется ломать бизнес-правила.

Нет в жизни щастя
16 фев 12, 06:05    [12100254]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Crimean
Member

Откуда:
Сообщений: 13147
Lepsik,

при выполнении "лабораторки" (не этой, схожей, но веток было не 128 а 64 и менее) хорошо доставляло раскладывание критичных таблиц и их индексов на многофайловые файлгруппы. я бы с этого начал
16 фев 12, 10:31    [12100860]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Александр Гладченко
Member

Откуда:
Сообщений: 10802
Блог
squid,

...мдя, действительно, лажа в коде :(

Причём, этот код встречается и в других документах, уже с небольшими правками: http://www.microsoft.com/download/en/details.aspx?id=26665
Кстати, сдвиги на единицу не помогут если баз предельное количество или файлов больше сотни :(

Извиняюсь, что не копал глубоко код при переводе. На глаз незаметно было, а латчей таких у меня не часто можно найти...
16 фев 12, 12:15    [12101970]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Александр Гладченко
Member

Откуда:
Сообщений: 10802
Блог
Вот это вроде в любых комбинациях работает (выше предложил squid):

SELECT	 file_index
	,page_index
	,SUBSTRING(resource_description, 0, file_index)
	,SUBSTRING(resource_description, file_index + 1, page_index - file_index - 1)
	,SUBSTRING(resource_description, page_index + 1, LEN(resource_description))
FROM (SELECT  CHARINDEX(':', resource_description) AS file_index
            , CHARINDEX(':', resource_description, CHARINDEX(':', resource_description)+1) AS page_index  
            , resource_description 
      FROM  (Select '1:22:333' as resource_description) as wt
     ) as rd


Сообщение было отредактировано: 16 фев 12, 12:57
16 фев 12, 12:40    [12102204]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
squid
Member

Откуда: LA
Сообщений: 590
Вернемся к теме.
скрипт корявый, сразу и не заметил и к слову это не первый автор блогов который наступает на грабли.
вот объеденение таблиц из кода
JOIN sys.partitions p ON au.container_id = p.partition_id


где au -DMV allocation_units
MSDN предписывает использовать объеденеие с partitions с учетом типа еденицы распределения (Type)
цитата

автор
container_id bigint
ID of the storage container associated with the allocation unit.

If type = 1 or 3, container_id = sys.partitions.hobt_id.
If type is 2, then container_id = sys.partitions.partition_id.
0 = Allocation unit marked for deferred drop



где type

автор
0 = Dropped
1 = In-row data (all data types, except LOB data types)
2 = Large object (LOB) data (text, ntext, image, xml, large value types, and CLR user-defined types)
3 = Row-overflow data


в приведенном примере, скрипт реагирует только на еденицы распределения BLOB, коими страницы индекса не являются (max key len 900 bytes)
ЗЫ
1.У меня вообще сомнения что он рабочий.
2.Этот ляп как под копирку у всех блоггеров.
22 фев 12, 12:46    [12136237]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
Александр Гладченко
Member

Откуда:
Сообщений: 10802
Блог
squid,

А можна увидеть исправленный Вами вариант этого сценария?

К слову, я когда переводил - даже не пытался особенно промоделировать сценарий, мне сама идея понравилась, вот ради неё этот перевод в моём блоге и появился. Я же ожидания смотрю по другому: http://msmvps.com/blogs/gladchenko/archive/2010/12/16/1784447.aspx
22 фев 12, 12:53    [12136298]     Ответить | Цитировать Сообщить модератору
 Re: about article: Как справиться с PAGELATCH при больших INSERT-нагрузках  [new]
squid
Member

Откуда: LA
Сообщений: 590
Александр, я смотрю на скрипт взглядом со стороны, поскольку не имею столь мощного железа в распоряжении для проведения тестов, соответственно отловить блох тоже не имею возможности.

Что точно могу сказать (использую сам), так это следует заменить

JOIN sys.partitions p ON au.container_id = p.partition_id


на

JOIN sys.partitions p ON 
        (au.container_id = p.partition_id AND au = 2)
       OR
        (au.container_id = p.hobt_id      AND au.type in (1,3))


Но поскольку мы говорим о блокировках возникающих на страницах индекса (не BLOB еденицы распределения),
я бы предложил объеденеие покороче
JOIN sys.partitions p ON 
        (au.container_id = p.hobt_id      AND au.type in (1,3))



ЗЫ. за ссылку спасибо, я обязательно посмотрю Вашу методику, мне это очень интересно, поскольку занимаюсь созданием тулзы (GUI + ДБ часть) для визуализации статистики ожиданий, как общей так и условно мгновенной.
22 фев 12, 13:25    [12136625]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить