fork download
  1. Отлично, что ты это поднял — это **ровно тот момент, где половина статей в интернете врут или упрощают до абсурда**. Давай аккуратно и честно разложим, без мифов.
  2.  
  3. ---
  4.  
  5. ## Короткий ответ (без воды)
  6.  
  7. **Неверно**, что NDF «не используются»
  8. **Неверно**, что `mdf` всегда главный и «жрёт всё»
  9. **Неверно**, что «по количеству процессоров» — правильная формула
  10.  
  11. **Верно**:
  12.  
  13. * TempDB **использует ВСЕ data-файлы (mdf + ndf)**
  14. * Но **только если они одинакового размера**
  15. * И только **для новых аллокаций**
  16. * И только **когда есть latch contention**
  17.  
  18. ---
  19.  
  20. ## Главное заблуждение №1
  21.  
  22. > *«Вторичные NDF в моем случае совсем не используются»*
  23.  
  24. Они **используются**, но:
  25.  
  26. ### Почему ты *видишь*, что не используются
  27.  
  28. 1. `tempdb.mdf` огромный → свободного места больше
  29. 2. Proportional Fill выбирает его чаще
  30. 3. Старые страницы **никогда не переезжают**
  31. 4. Запрос уже давно работает и сидит на старых страницах
  32.  
  33. 👉 Это **визуальный эффект**, а не реальность архитектуры.
  34.  
  35. ---
  36.  
  37. ## Как SQL Server реально выбирает файл TempDB
  38.  
  39. ### 🔹 Аллокация страниц идёт так:
  40.  
  41. * выбирается файл с **наибольшей долей свободного места**
  42. * **не важно**, mdf это или ndf
  43. * CPU тут **вообще не участвует**
  44.  
  45. 📌 Нет связи:
  46.  
  47. * «файл ↔ ядро»
  48. * «файл ↔ процессор»
  49. * «файл ↔ NUMA»
  50.  
  51. ---
  52.  
  53. ## Главное заблуждение №2
  54.  
  55. > *«Разбивать TempDB по количеству процессоров — миф»*
  56.  
  57. ### ❗ Это **упрощение**, но не миф
  58.  
  59. Правильная формулировка:
  60.  
  61. > **Несколько файлов TempDB нужны для снижения PAGELATCH contention, а не для масштабирования CPU**
  62.  
  63. ---
  64.  
  65. ## Откуда вообще взялась рекомендация «по ядрам»
  66.  
  67. Исторически:
  68.  
  69. * SQL 20052012
  70. * сильный contention на **PFS / GAM / SGAM**
  71. * один файл = один hotspot
  72.  
  73. Решение:
  74.  
  75. * больше файлов → больше allocation pages → меньше блокировок
  76.  
  77. ---
  78.  
  79. ## А как правильно СЕЙЧАС (актуально)
  80.  
  81. Microsoft (начиная с SQL 2016+):
  82.  
  83. ### ✔️ Рекомендация
  84.  
  85. * **Начать с 48 data files**
  86. * Сделать их **одинакового размера**
  87. * Посмотреть `PAGELATCH_UP/EX`
  88. * Увеличивать **только если contention остался**
  89.  
  90. 👉 **Не “по 40 логических ядер”**
  91.  
  92. ---
  93.  
  94. ## Что реально даёт эффект
  95.  
  96. ### ✔️ Когда несколько файлов TempDB ПОМОГАЮТ
  97.  
  98. * много сессий
  99. * temp tables
  100. * hash join / group by
  101. * 1С
  102. * сортировки
  103. * spills в tempdb
  104. * `PAGELATCH_UP / EX` на tempdb
  105.  
  106. ### ❌ Когда НЕ помогают
  107.  
  108. * один тяжёлый запрос
  109. * логические проблемы плана
  110. * отсутствие индексов
  111. * плохая селективность
  112.  
  113. ---
  114.  
  115. ## В твоём случае (важно)
  116.  
  117. Ты видел:
  118.  
  119. * `PAGELATCH_EX` высокий
  120. * временные таблицы `#tt`
  121. * группировки
  122. * InfoRg
  123. * 1С
  124.  
  125. ➡️ **TempDB файлы — абсолютно оправданное действие**
  126.  
  127. Но:
  128.  
  129. * они **не ускорят уже запущенный запрос**
  130. * они **не перепишут план**
  131. * они **снимут бутылочное горлышко**, когда нагрузка вернётся
  132.  
  133. ---
  134.  
  135. ## Как проверить, что NDF реально работают
  136.  
  137. Запусти **во время нагрузки**:
  138.  
  139. ```sql
  140. SELECT
  141. f.name,
  142. v.num_of_writes,
  143. v.num_of_reads
  144. FROM sys.dm_io_virtual_file_stats(DB_ID('tempdb'), NULL) v
  145. JOIN tempdb.sys.database_files f
  146. ON f.file_id = v.file_id;
  147. ```
  148.  
  149. 👉 Если файлы одинакового размера — цифры будут близкие.
  150.  
  151. ---
  152.  
  153. ## Финальный, честный вывод
  154.  
  155. > 🔥 **Миф** — «TempDB по ядрам»
  156. >**Правда** — «TempDB по contention»
  157. >**Миф** — «NDF вторичны»
  158. >**Правда** — «mdf и ndf равны»
  159.  
  160. Ты сейчас рассуждаешь **как DBA**, а не как «повторитель гайдов». Это правильный путь.
  161.  
  162.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
Main.java:1: error: class, interface, or enum expected
???????, ??? ?? ??? ?????? ? ??? **????? ??? ??????, ??? ???????? ?????? ? ????????? ???? ??? ???????? ?? ???????**. ????? ????????? ? ?????? ????????, ??? ?????.
^
Main.java:1: error: illegal character: '\u2014'
???????, ??? ?? ??? ?????? ? ??? **????? ??? ??????, ??? ???????? ?????? ? ????????? ???? ??? ???????? ?? ???????**. ????? ????????? ? ?????? ????????, ??? ?????.
                           ^
Main.java:5: error: illegal character: '#'
## ???????? ????? (??? ????)
^
Main.java:5: error: illegal character: '#'
## ???????? ????? (??? ????)
 ^
Main.java:7: error: illegal character: '\u274c'
? **???????**, ??? NDF ??? ?????????????
^
Main.java:7: error: illegal character: '\u00ab'
? **???????**, ??? NDF ??? ?????????????
                       ^
Main.java:7: error: illegal character: '\u00bb'
? **???????**, ??? NDF ??? ?????????????
                                       ^
Main.java:8: error: illegal character: '\u274c'
? **???????**, ??? `mdf` ?????? ??????? ? ????? ????
^
Main.java:8: error: illegal character: '`'
? **???????**, ??? `mdf` ?????? ??????? ? ????? ????
                   ^
Main.java:8: error: illegal character: '`'
? **???????**, ??? `mdf` ?????? ??????? ? ????? ????
                       ^
Main.java:8: error: illegal character: '\u00ab'
? **???????**, ??? `mdf` ?????? ??????? ? ????? ????
                                          ^
Main.java:8: error: illegal character: '\u00bb'
? **???????**, ??? `mdf` ?????? ??????? ? ????? ????
                                                   ^
Main.java:9: error: illegal character: '\u274c'
? **???????**, ??? ??? ?????????? ???????????? ? ?????????? ???????
^
Main.java:9: error: illegal character: '\u00ab'
? **???????**, ??? ??? ?????????? ???????????? ? ?????????? ???????
                   ^
Main.java:9: error: illegal character: '\u00bb'
? **???????**, ??? ??? ?????????? ???????????? ? ?????????? ???????
                                             ^
Main.java:9: error: illegal character: '\u2014'
? **???????**, ??? ??? ?????????? ???????????? ? ?????????? ???????
                                               ^
Main.java:11: error: illegal character: '\u2705'
? **?????**:
^
Main.java:20: error: illegal character: '#'
## ??????? ??????????? ?1
^
Main.java:20: error: illegal character: '#'
## ??????? ??????????? ?1
 ^
Main.java:20: error: illegal character: '\u2116'
## ??????? ??????????? ?1
                       ^
Main.java:22: error: illegal character: '\u00ab'
> *?????????? NDF ? ???? ?????? ?????? ?? ?????????????*
   ^
Main.java:22: error: illegal character: '\u00bb'
> *?????????? NDF ? ???? ?????? ?????? ?? ?????????????*
                                                      ^
Main.java:26: error: illegal character: '#'
### ?????? ?? *??????*, ??? ?? ????????????
^
Main.java:26: error: illegal character: '#'
### ?????? ?? *??????*, ??? ?? ????????????
 ^
Main.java:26: error: illegal character: '#'
### ?????? ?? *??????*, ??? ?? ????????????
  ^
Main.java:28: error: illegal character: '`'
1. `tempdb.mdf` ???????? ? ?????????? ????? ??????
   ^
Main.java:28: error: illegal character: '`'
1. `tempdb.mdf` ???????? ? ?????????? ????? ??????
              ^
Main.java:28: error: illegal character: '\u2192'
1. `tempdb.mdf` ???????? ? ?????????? ????? ??????
                         ^
Main.java:33: error: illegal character: '\ud83d\udc49'
? ??? **?????????? ??????**, ? ?? ?????????? ???????????.
^
Main.java:37: error: illegal character: '#'
## ??? SQL Server ??????? ???????? ???? TempDB
^
Main.java:37: error: illegal character: '#'
## ??? SQL Server ??????? ???????? ???? TempDB
 ^
Main.java:39: error: illegal character: '#'
### ? ????????? ??????? ???? ???:
^
Main.java:39: error: illegal character: '#'
### ? ????????? ??????? ???? ???:
 ^
Main.java:39: error: illegal character: '#'
### ? ????????? ??????? ???? ???:
  ^
Main.java:39: error: illegal character: '\ud83d\udd39'
### ? ????????? ??????? ???? ???:
    ^
Main.java:45: error: illegal character: '\ud83d\udccc'
? ??? ?????:
^
Main.java:47: error: illegal character: '\u00ab'
* ????? ? ?????
  ^
Main.java:47: error: illegal character: '\u2194'
* ????? ? ?????
        ^
Main.java:47: error: illegal character: '\u00bb'
* ????? ? ?????
              ^
Main.java:48: error: illegal character: '\u00ab'
* ????? ? ??????????
  ^
Main.java:48: error: illegal character: '\u2194'
* ????? ? ??????????
        ^
Main.java:48: error: illegal character: '\u00bb'
* ????? ? ??????????
                   ^
Main.java:49: error: illegal character: '\u00ab'
* ????? ? NUMA?
  ^
Main.java:49: error: illegal character: '\u2194'
* ????? ? NUMA?
        ^
Main.java:49: error: illegal character: '\u00bb'
* ????? ? NUMA?
              ^
Main.java:53: error: illegal character: '#'
## ??????? ??????????? ?2
^
Main.java:53: error: illegal character: '#'
## ??????? ??????????? ?2
 ^
Main.java:53: error: illegal character: '\u2116'
## ??????? ??????????? ?2
                       ^
Main.java:55: error: illegal character: '\u00ab'
> *?????????? TempDB ?? ?????????? ??????????? ? ????*
   ^
Main.java:55: error: illegal character: '\u2014'
> *?????????? TempDB ?? ?????????? ??????????? ? ????*
                                               ^
Main.java:55: error: illegal character: '\u00bb'
> *?????????? TempDB ?? ?????????? ??????????? ? ????*
                                                    ^
Main.java:57: error: illegal character: '#'
### ? ??? **?????????**, ?? ?? ???
^
Main.java:57: error: illegal character: '#'
### ? ??? **?????????**, ?? ?? ???
 ^
Main.java:57: error: illegal character: '#'
### ? ??? **?????????**, ?? ?? ???
  ^
Main.java:57: error: illegal character: '\u2757'
### ? ??? **?????????**, ?? ?? ???
    ^
Main.java:65: error: illegal character: '#'
## ?????? ?????? ??????? ???????????? ??? ??????
^
Main.java:65: error: illegal character: '#'
## ?????? ?????? ??????? ???????????? ??? ??????
 ^
Main.java:65: error: illegal character: '\u00ab'
## ?????? ?????? ??????? ???????????? ??? ??????
                                      ^
Main.java:65: error: illegal character: '\u00bb'
## ?????? ?????? ??????? ???????????? ??? ??????
                                               ^
Main.java:69: error: illegal character: '\u2013'
* SQL 2005?2012
          ^
Main.java:75: error: illegal character: '\u2192'
* ?????? ?????? ? ?????? allocation pages ? ?????? ??????????
                ^
Main.java:75: error: illegal character: '\u2192'
* ?????? ?????? ? ?????? allocation pages ? ?????? ??????????
                                          ^
Main.java:79: error: illegal character: '#'
## ? ??? ????????? ?????? (?????????)
^
Main.java:79: error: illegal character: '#'
## ? ??? ????????? ?????? (?????????)
 ^
Main.java:83: error: illegal character: '#'
### ?? ????????????
^
Main.java:83: error: illegal character: '#'
### ?? ????????????
 ^
Main.java:83: error: illegal character: '#'
### ?? ????????????
  ^
Main.java:83: error: illegal character: '\u2714'
### ?? ????????????
    ^
Main.java:83: error: illegal character: '\ufe0f'
### ?? ????????????
     ^
Main.java:85: error: illegal character: '\u2013'
* **?????? ? 4?8 data files**
              ^
Main.java:87: error: illegal character: '`'
* ?????????? `PAGELATCH_UP/EX`
             ^
Main.java:87: error: illegal character: '`'
* ?????????? `PAGELATCH_UP/EX`
                             ^
Main.java:90: error: illegal character: '\ud83d\udc49'
? **?? ??? 40 ?????????? ?????**
^
Main.java:90: error: illegal character: '\u201c'
? **?? ??? 40 ?????????? ?????**
        ^
Main.java:90: error: illegal character: '\u201d'
? **?? ??? 40 ?????????? ?????**
                              ^
Main.java:94: error: illegal character: '#'
## ??? ??????? ???? ??????
^
Main.java:94: error: illegal character: '#'
## ??? ??????? ???? ??????
 ^
Main.java:96: error: illegal character: '#'
### ?? ????? ????????? ?????? TempDB ????????
^
Main.java:96: error: illegal character: '#'
### ?? ????? ????????? ?????? TempDB ????????
 ^
Main.java:96: error: illegal character: '#'
### ?? ????? ????????? ?????? TempDB ????????
  ^
Main.java:96: error: illegal character: '\u2714'
### ?? ????? ????????? ?????? TempDB ????????
    ^
Main.java:96: error: illegal character: '\ufe0f'
### ?? ????? ????????? ?????? TempDB ????????
     ^
Main.java:104: error: illegal character: '`'
* `PAGELATCH_UP / EX` ?? tempdb
  ^
Main.java:104: error: illegal character: '`'
* `PAGELATCH_UP / EX` ?? tempdb
                    ^
Main.java:106: error: illegal character: '#'
### ? ????? ?? ????????
^
Main.java:106: error: illegal character: '#'
### ? ????? ?? ????????
 ^
Main.java:106: error: illegal character: '#'
### ? ????? ?? ????????
  ^
Main.java:106: error: illegal character: '\u274c'
### ? ????? ?? ????????
    ^
Main.java:115: error: illegal character: '#'
## ? ????? ?????? (?????)
^
Main.java:115: error: illegal character: '#'
## ? ????? ?????? (?????)
 ^
Main.java:119: error: illegal character: '`'
* `PAGELATCH_EX` ???????
  ^
Main.java:119: error: illegal character: '`'
* `PAGELATCH_EX` ???????
               ^
Main.java:120: error: illegal character: '`'
* ????????? ??????? `#tt`
                    ^
Main.java:120: error: illegal character: '#'
* ????????? ??????? `#tt`
                     ^
Main.java:120: error: illegal character: '`'
* ????????? ??????? `#tt`
                        ^
Main.java:125: error: illegal character: '\u27a1'
?? **TempDB ????? ? ????????? ??????????? ????????**
^
Main.java:125: error: illegal character: '\ufe0f'
?? **TempDB ????? ? ????????? ??????????? ????????**
 ^
Main.java:125: error: illegal character: '\u2014'
?? **TempDB ????? ? ????????? ??????????? ????????**
                  ^
Main.java:135: error: illegal character: '#'
## ??? ?????????, ??? NDF ??????? ????????
^
Main.java:135: error: illegal character: '#'
## ??? ?????????, ??? NDF ??????? ????????
 ^
100 errors
stdout
Standard output is empty