Database
 sql >> база данни >  >> RDS >> Database

Митове за производителността:Променливите в таблицата винаги са в паметта

Гост автор:Дерик Хамър (@SQLHammer)


Наскоро Аарон Бертранд публикува блог за вредните, широко разпространени митове за производителността на SQL сървъра. Като продължение на тази поредица от блогове, ще опровергая този често срещан мит:

"Променливите на таблицата винаги са в паметта, следователно по-бързи от временните таблици."

Четене на ръководството

Отивайки направо към източника, погледнах статията на Books Online за таблици, която включва променливи в таблицата. Въпреки че статията споменава предимствата от използването на таблични променливи, фактът, че те са 100% в паметта, очевидно липсва.

Липсващото утвърждаване обаче не означава отрицателно. След като бяха пуснати OLTP таблици в паметта, сега има много повече документация в BOL за обработка в паметта. Там намерих тази статия за по-бързото правене на променливи на временни таблици и таблици чрез използване на оптимизация на паметта.

Цялата статия се върти около това как да накарате вашите временни обекти да използват функцията OLTP в паметта и тук намерих утвърдителното, което търсех.

"Традиционната променлива на таблицата представлява таблица в базата данни tempdb. За много по-бърза производителност можете да оптимизирате паметта си променливата на таблицата."

Табличните променливи не са конструкции в паметта. За да използвате технологията в паметта, трябва изрично да дефинирате ТИП, който е оптимизиран за паметта, и да използвате този ТИП, за да дефинирате променливата на вашата таблица.

Докажи го

Документацията е едно, но да я видя с очите си е съвсем друго. Знам, че временните таблици създават обекти в tempdb и ще записват данни на диск. Първо ще ви покажа как изглежда това за временните таблици и след това ще използвам същия метод, за да потвърдя хипотезата, че променливите на таблицата действат по същия начин.

Анализ на регистрационния запис

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

USE tempdb;
GO
 
CHECKPOINT;
GO
 
SELECT COUNT(*) [Count] 
  FROM sys.fn_dblog (NULL, NULL);
 
SELECT [Transaction Name]
  FROM sys.fn_dblog (NULL, NULL)
  WHERE [Transaction Name] IS NOT NULL;


Неколкократното изпълнение на T-SQL доведе до последователен брой три записа на SQL Server 2016 SP1.

Това създава временна таблица и показва записа на обекта, доказвайки, че това е реален обект в tempdb.

USE tempdb;
GO
 
DROP TABLE IF EXISTS #tmp;
GO
 
CREATE TABLE #tmp (id int NULL);
 
SELECT name
  FROM sys.objects o
  WHERE is_ms_shipped = 0;

Сега отново ще покажа записите в дневника. Няма да стартирам повторно командата CHECKPOINT.

Бяха записани двадесет и един регистрационен запис, което доказва, че това са записи на диск и нашата CREATE TABLE ясно е включена в тези регистрационни записи.

За да сравня тези резултати с таблични променливи, ще нулирам експеримента, като стартирам CHECKPOINT и след това изпълня T-SQL по-долу, създавайки променлива на таблица.

USE tempdb;
GO
 
DECLARE @var TABLE (id int NULL);
 
SELECT name
  FROM sys.objects o
  WHERE is_ms_shipped = 0;

Отново имаме нов обектен запис. Този път обаче името е по-случайно, отколкото при временните таблици.

Има осемдесет и два нови регистрационни записи и имена на транзакции, доказващи, че моята променлива се записва в дневника и следователно на диска.

Всъщност в паметта

Сега е време да направя така, че записите в дневника да изчезнат.

Създадох OLTP файлова група в паметта и след това създадох оптимизиран за памет тип таблица.

USE Test;
GO
 
CREATE TYPE dbo.inMemoryTableType  
  AS TABLE 
  ( id INT NULL INDEX ix1 )
  WITH (MEMORY_OPTIMIZED = ON);  
GO

Изпълних отново CHECKPOINT и след това създадох оптимизираната за памет таблица.

USE Test;
GO
 
DECLARE @var dbo.inMemoryTableType;
 
INSERT INTO @var (id) VALUES (1)
 
SELECT * from @var;  
GO

След преглед на дневника не видях никаква активност в дневника. Този метод всъщност е 100% в паметта.

Отнесете

Табличните променливи използват tempdb подобно на начина, по който временните таблици използват tempdb. Табличните променливи не са конструкции в паметта, но могат да се превърнат в тях, ако използвате оптимизирани от паметта типове таблици, дефинирани от потребителя. Често намирам, че временните таблици са много по-добър избор от променливите на таблицата. Основната причина за това е, че променливите в таблицата нямат статистически данни и, в зависимост от версията и настройките на SQL Server, оценките на редовете се оказват 1 ред или 100 реда. И в двата случая това са предположения и се превръщат в пагубни части от дезинформация в процеса на оптимизиране на заявката ви.

Обърнете внимание, че някои от тези разлики в функциите може да се променят с течение на времето – например в последните версии на SQL Server можете да създадете допълнителни индекси върху променлива на таблица, използвайки синтаксис на вграден индекс. Следващата таблица има три индекса; първичния ключ (клъстериран по подразбиране) и два неклъстерирани индекса:

DECLARE @t TABLE
(
  a int PRIMARY KEY,
  b int,
  INDEX x (b, a DESC),
  INDEX y (b DESC, a)
);

Има страхотен отговор на DBA Stack Exchange, където Мартин Смит изчерпателно описва разликите между променливите на таблицата и #temp таблиците:

  • Каква е разликата между временна таблица и таблична променлива в SQL Server?

За автора

Дерик е специалист по данни и току-що създаден MVP на Microsoft Data Platform, фокусиран върху SQL Server. Страстта му се фокусира върху високата наличност, възстановяването при бедствия, непрекъснатата интеграция и автоматизираната поддръжка. Опитът му обхваща дългосрочно администриране на бази данни, консултации и предприемачески начинания, работещи във финансовата и здравната индустрия. Понастоящем той е старши администратор на база данни, отговарящ за екипа за операции с бази данни в Световната централа на Subway Franchise. Когато не е на час или не води блог в SQLHammer.com, Дерик посвещава времето си на #sqlfamily като лидер на главите за потребителската група на FairfieldPASS SQL Server в Стамфорд, Коннектикут.
  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Планове за копаене:Не само за кеша на плановете

  2. Как филтрираните индекси могат да бъдат по-мощна функция

  3. Как да получите вчерашна дата в T-SQL

  4. Трансформирайте ODBC данни в CloverDX

  5. 2 начина за избор на редове, които съответстват на всички елементи в списък (T-SQL)