4 нояб. 2010 г.

Длина имени параметра и производительность

Автор: Грант Фритчи (Grant Fritchey).
Оригинал статьи: Parameter Name Size And Performance

Недавно я увидел высказывание: "Длина имени параметра не влияет на производительность". Моя первая мысль была: "Конечно, еще бы!". Но затем была другая: "А ты уверен?". И вы знаете, я не был уверен.

Я предположил, что если длина имени параметра действительно влияет на производительность, то это явно должно отразиться на размере плана запроса. Верно? Если это влияет на память, и, следовательно, на производительность, вероятно, доказательство этого можно увидеть именно в плане запроса. Я написал два запроса:

DECLARE @ЭтоОченьОченьДлинноеИмяПараметраКотороеДействительноНелепоНоПоказываетЧтоДлинаИмениПараметраНеВлияетНаПроизводительность int
SET @ЭтоОченьОченьДлинноеИмяПараметраКотороеДействительноНелепоНоПоказываетЧтоДлинаИмениПараметраНеВлияетНаПроизводительность = 572
SELECT soh.SalesOrderID
,sod.SalesOrderDetailID
FROM Sales.SalesOrderHeader AS soh
JOIN Sales.SalesOrderDetail AS sod
ON soh.SalesOrderID = sod.SalesOrderID
WHERE soh.SalesOrderID = @ЭтоОченьОченьДлинноеИмяПараметраКотороеДействительноНелепоНоПоказываетЧтоДлинаИмениПараметраНеВлияетНаПроизводительность

DECLARE @v int
SET @v = 572
SELECT soh.SalesOrderID
,sod.SalesOrderDetailID
FROM Sales.SalesOrderHeader AS soh
JOIN Sales.SalesOrderDetail AS sod
ON soh.SalesOrderID = sod.SalesOrderID
WHERE soh.SalesOrderID = @v

Выполните их для базы данных "AdventureWorks2008R2", и получите два отдельных, но похожих, плана выполнения запроса.



Они выглядят похоже, но как убедиться в том, что они разные? После выполнения следующего запроса

SELECT deqs.creation_time, deqs.query_hash, deqs.query_plan_hash
FROM sys.dm_exec_query_stats AS deqs
CROSS APPLY sys.dm_exec_query_plan(deqs.plan_handle) AS deqp
CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest
WHERE dest.text LIKE '%SELECT soh.SalesOrderID%'

был получен такой результат:

creation_timequery_hashquery_plan_hash
2010-10-15 19:55:39.4730x8D0FB9D524B8DD4D0x13707445560737BA
2010-10-15 19:55:39.5530x8D0FB9D524B8DD4D0x13707445560737BA

Два разных запроса, но с одинаковыми значениями хэшей. Сгенерированные планы почти одинаковы, но явно разные вследствие использования разных параметров, включая чудовищно длинное имя. Как увидеть, есть ли разница, влияющая на производительность? Как насчет свойств плана выполнения? Для начала посмотрим на свойства оператора SELECT для запроса с длинным именем параметра.


Особо следует отметить свойство "Размер плана в кэш-памяти". Сравним его с аналогичным свойством плана запроса с коротким именем параметра.



Если вы сравните их, то заметите, что они одинаковы. В действительности, если вы посмотрите, то увидите, что значения почти всех остальных свойств, в т.ч. "CompileMemory", одинаковы. На основании этих сведений, я делаю вывод о том, что длина имени параметра не оказывает влияния на производительность, ни положительного, ни отрицательного. Но почему?

Я не уверен на 100%, но на основании известных мне вещей, думаю так. Algebrizer внутри оптимизатора запросов анализирует все объекты, на которые ссылается план запроса. Он присваивает им значения, а также идентификаторы для этого плана, - это часть сбора информации для математической части оптимизатора запросов. Держу пари, он просто присваивает значения параметрам того же типа, что и значение, если не то же самое значение, и размер значения сохраняется от одного плана к другому.

Это означает, что вы не уменьшите объем потребляемой памяти, используя параметры @a, @b, @c, а на самом деле подразумевая @ReferenceCount, @MaxRetries, @BeginDate. Думаю ли я, что следует использовать параметры с чрезвычайно длинными именами, как показано выше? Нет, конечно, нет, потому что это делает код TSQL менее понятным. То же самое относится и к параметрам со слишком короткими именами.

Не пишите трудночитаемый код TSQL. Это не улучшает производительность.

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

Отправить комментарий