Дали това необходими временни таблици, в клуба за програмисти

Повечето от литературата, която се препоръчва да се въздържат от използването на временни таблици, с право твърдят, че това може да доведе до проблеми с производителността се дължи на блокиране на tempdb при създаване на временна таблица, за да се увеличи броят на / O операции I с помощта на временна таблица, както и възможността за заключване на tempdb, ако създаването на и последващите операции възникват с временна таблица в една сделка. И това не е, за да говорим за многобройните проблеми, които SQL Server изпитва, когато се занимават с временни таблици - виж базата знания списък статия по-долу .. Без да се подложи на горните съмнения, аз ще дам някои аргументи в полза на временни таблици. Признавам, че не се използват или да намерят причини да се използват глобални временни таблици, така че няма да се намери тук обсъждане на тези таблици.

Какво можем да използваме една маса температура?

Ето няколко причини защо ли да използвам временни таблици в работата си: запазване на резултатите, причинени от съхранената процедура; намаляване на броя на линии, използвани в съединенията; съчетават данни от различни източници; и подмяна на курсора.

Както молбата ви става все по-сложна, ще откриете повтарящи се блокове от код в рамките на една заявка или няколко искания. Такава повторна употреба стимулира създаването на съхранена процедура, която съдържа два екземпляра код, с призива си към подходящите места. Това може да доведе до появата на голям брой съхранени процедури във вашата база данни, но до голяма степен намалява поддръжка, защото при смяна на функционалността, което трябва да се промени кода на само един въпрос, а не многото искания, които все още могат да се намерят. Аз използвам тази техника доста често, и това често ме принуждава да се използва временна таблица за съхранение на резултатите от съхранена процедура, защото Transact-SQL не позволява използването на съхранената процедура резултатите във вид на таблица. Това е може би основната причина за използването на временни таблици в моя код.

Аз много често трябва да се съчетаят таблици на заявки, съдържащи около 10, 100 и 20 милиона линии, следвани от сортиране за показване на последните промени в първия ред на резултата. Дори и с подходящи показатели и използване на клаузата за това къде да филтрирате и принуден да използва индекс заявката за изпълнение е неприемливо (защото прилагането, с които работя, се използва по такъв начин, че благоприятно време за отговор на искане в секунди), а често и сортиране причини огромни загуби на производителност, както и огромно натоварване tempdb. Доста често, се оказа, че използването на подходящи временни таблици за всеки един от постоянните масите да съдържат филтрира с помощта на офертата на данни, където, преди да направи връзката и сортиране, така увеличи производителността на запитването, аз всъщност може да го приложи, без да се притеснявате за производителността или въздействието на tempdb база данни. По-долу е една много проста заявка, като показва.

SELECT table1.numCustID, table2.strPhoneNumber, table3.strPhoneNumberCalled
ОТ dbo.table1 таблица 1
INNER JOIN dbo.table2 Таблица 2
ON table1.numBillID = table2.numBillID
INNER JOIN dbo.table3 table3
ON table2.numBillDtlID = table3.numBillDtlID
КЪДЕТО table1.numCustID = "5555"
И table2.strPhoneNumber = '5555555555'
И table3.strPhoneNumberCalled = '1234561234'
ORDER BY table3.dtmCalled DESC

(Този въпрос не съвпада с нито схема, всяка съществуваща заявка в компанията Verizon. Тя е създадена, за да покажат по-особен проблем от хипотетично основа на данни, свързани с телекомуникациите.)

Нова заявка:

(Обичам да наричам временна таблица на име съхранена процедура, която тя създава, така че бързо да се оправи всички проблеми в tempdb, свързан с използването на временни таблици.)

Създаване на таблица # tquery2a
(Multiplecolumns типове данни)

Създаване на таблица # tquery2b
(Mulitplecolumns типове данни)

INSERT INTO # tquery2a
Добави колони ОТ КОИТО dbo.table2 table2.strPhoneNumber = "5555555555"

INSERT INTO # tquery2b
Добави колони ОТ КОИТО dbo.table3 table3.strPhoneNumberCalled = "1234561234"

SELECT table1.numCustID, # tquery2a.strPhoneNumber, # tquery2b.strPhoneNumberCalled
ОТ dbo.table1 таблица 1
INNER JOIN # tquery2a # tquery2a
ON table1.numBillID = # tquery2a.numBillID
INNER JOIN # tquery2b # tquery2b
ON # tquery2a.numBillDtlID = # tquery2b.numBillDtlID
КЪДЕТО table1.numCustID = "5555"
ORDER BY # tquery2b.dtmCalled DESC

Искате ли да - тя или вярвам - не, но този метод е много по-бързо, отколкото първоначалното искане, особено когато е налице ПОРЪЧКА предложение.

Последният аргумент в полза на временна таблица - курсор замяна. Не ми харесва курсори и призовават да направи всичко възможно, за да подмените мишката (въпреки че искате да се оцени ефективността на своите решения относно изпълнението на курсора). Един трик да използвам е да имитират основната причина, че обикновено се натрупва над - прогресивна ITERATE чрез набор резултат и извърши действие, въз основа на данните в този ред. По-долу - кратък въпрос, който демонстрира тази логика чрез получаване имената на всички потребителски маси и изпълнява sp_spaceused на всяка маса.

SET NOCOUNT ON
ДЕКЛАРИРАМЕ @lngTabCount ЦЯЛО
ДЕКЛАРИРАМЕ @lngLoopCount ЦЯЛО
ДЕКЛАРИРАМЕ @strTabName SYSNAME

Създаване на таблица #tTables
(
numID INTEGER ИДЕНТИЧНОСТ (1,1)
,strTableName SYSNAME
)

INSERT INTO #tTables (strTableName)
Изберете името ОТ КЪДЕ dbo.sysobjects xtype = "U"

SET @lngTabCount = @@ ROWCOUNT
SET @lngLoopCount = @lngTabCount

ДОКАТО @lngLoopCount <> 0
ЗАПОЧНЕТЕ
SET @strTabName = (SELECT strTableName ОТ КОИТО #tTables numID = @lngLoopCount)
EXEC sp_spaceused @strTabName
SET @lngLoopCount = @lngLoopCount - 1
END

DROP TABLE #tTables
GO

Такова действие без курсор стрелка и свързаните с тях проблеми с производителността.

Как можете да работите без използването на временна таблица?

Сега, когато съм ви показва няколко ситуации, в които е оправдано използването на временни таблици, нека да поговорим за това, което можете да направите, за да е възможно да се избегне използването на временна таблица.

Всеки от тези методи се разглежда като възможно алтернативно решение на използването на временна таблица. Основното нещо тук - за да оценят алтернативните начини за определяне дали може с основание да заменят използването на временни таблици, които обикновено са създадени от силата на навика. При създаването на различни техники и похвати, които можете да използвате временни таблици по-малко и по-малко, а дори ще изпитат дискомфорт при използване на временна таблица, вярвайки, че сигурно има начин да се направи без него.

Ако използвате временни таблици, оптимизира използването им.

Ако ситуацията диктува използването на временна таблица, след което трябва да направите няколко неща, за подобряване на нейната ефективност. На първо място, именно защото това е временна таблица, не се опитвайте да се сложи всички колони и всички редове от постоянния си маса, ако не се нуждаят от тях. Филтрирате данните, които влизат в временна таблица за ограничаване на минималния брой необходими колони и редове. На второ място, не използвайте SELECT INTO изявление за създаване на временни таблици. SELECT INTO изявление в кода трябва да се избягва на всяка цена, тъй като на локаут, той налага на системни обекти за дълго време, за да реши как да се изгради една маса. Отделете време, за да се напише скрипт за създаване на временна таблица и индивидуално вмъкнете в изявления на неговото завършване. Аз вярвам, че можете да използвате SELECT INTO, ако тя включва където 1 = 0, за да се създаде една маса в най-бързия начин, но не го правя само за да запишете няколко натискания на клавиши. На трето място, погледнете как да използвате временни таблици, за да се избегне прекомпилирате запомнена процедура. Обяснявам подробно в оптимизиране на статия на запомнени процедури прекомпилира. достъпно на моя сайт. Четвърто, проверка на необходимостта от струпани индекс на вашия временна таблица. Ако данните са големи, клъстерирани индекс ще ускори работата на вземане на проби разписанието, но трябва да се оценят разходите за изпълнение, за да създадете индекса и поставете на данни в таблица с групирана индекс. Това е един от тези методи, които трябва да бъдат проверени преди решението за избор на индекса и в двете версии с възможно най-високата набор от данни, които, според Вас, ще бъдат поставени в една временна таблица. И накрая, ние знаем, че когато завършва изпълнението на съхранената процедура и завършва на връзката, на временна таблица е изпускан, но защо го пазят, ако това вече не е необходима. Ако кодът ви създава и използва временна таблица, след което превключва на другите неща, които не използват тази таблица, извадете го в кода. Това освобождава ресурси за други tempdb обекти. Изтрия таблицата в края на съхранената процедура, дори когато прекратява връзката, но за да се избегнат евентуални проблеми, които могат да възникнат поради неизвестни грешки.

Въпреки временни таблици (по мое мнение) много по-добри, отколкото курсори, тяхната употреба води до спад в производителността. Тази статия се обсъждат накратко редица причини за използване на временни таблици, както и няколко алтернативни методи. трябва да се вземе конкретно решение в зависимост от ситуацията. Проверете молбата си с алтернативни подходи, преди да се създаде временна таблица, както и оценка на изпълнението на временни таблици; след това можете да направят информиран избор. Аз съм твърдо на мнение, въз основа на поуките (и това, въпреки че аз пиша тази статия), че преди да се приложи нещо чете книга или на уебсайт, трябва да го проверите по няколко различни начина. Направете го и умения за използване на Transact-SQL ще продължи да расте до ниво, където винаги ще има няколко различни начина за създаване на заявка.