Чи впливають нерелевантні стовпці на час запиту вибраних операторів?


10

Мені просто цікаво.

Скажімо, у вас є таблиця з 1 мільйон записів / рядків.

select order_value from store.orders

Чи має значення, чи має ця таблиця 1 поле, 2 поля чи 100 полів за фактичний час запиту? Я маю на увазі всі поля, крім "order_value".

Зараз я пересилаю дані до сховища даних. Іноді я скидаю поля в таблицю, які "можуть бути використані в майбутньому, коли-небудь" - але вони не запитуються зараз нічим. Чи впливатимуть ці "сторонні" поля на вибрані оператори, які не включають їх, прямо чи опосередковано (ні * я маю на увазі)?


Інформація про це доступна в Інтернеті. Ключовим моментом є отримання найсвіжішої інформації під час зміни технологій. Те, що ви запитуєте, настільки залежить від вашої конкретної установки, що не можна дати дуже гарну відповідь. Ключовим моментом, який слід пам’ятати, є те, що в міру переходу на SSD багато речей, які колись були дуже важливими для продуктивності, вже не відбувається.
Джо

Відповіді:


10

Це дійсно залежить від індексів та типів даних.

Використовуючи базу даних переповнення стека як приклад, так виглядає таблиця користувачів:

Горіхи

Він має PK / CX у стовпці Id. Отже, це сукупність даних таблиці, відсортованих за Id.

Маючи це єдиний індекс, SQL повинен прочитати все це (без колон LOB) у пам'яті, якщо його ще немає.

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SET STATISTICS TIME, IO ON 

SELECT u.Id
INTO  #crap1
FROM dbo.Users AS u

Час статистики та іо-профіль виглядає так:

Table 'Users'. Scan count 7, logical reads 80846, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2406 ms,  elapsed time = 446 ms.

Якщо я додаю додатковий некластеризований індекс лише на Id

CREATE INDEX ix_whatever ON dbo.Users (Id)

Зараз у мене набагато менший індекс, який задовольняє мій запит.

DBCC DROPCLEANBUFFERS-- Don't run this anywhere near prod.

SELECT u.Id
INTO  #crap2
FROM dbo.Users AS u

Профіль тут:

Table 'Users'. Scan count 7, logical reads 6587, physical reads 0, read-ahead reads 6549, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2344 ms,  elapsed time = 384 ms.

Ми можемо зробити набагато менше читань та заощадити трохи часу на процесорі.

Без додаткової інформації про ваше визначення таблиці я не можу реально спробувати відтворити те, що ви намагаєтесь краще виміряти.

Але ви говорите, що, якщо в цьому самотньому стовпчику немає конкретного індексу, інші стовпці / поля також будуть скановані? Це лише недолік, притаманний дизайну столових рядів? Чому б сканувати невідповідні поля?

Так, це характерно для таблиць рядків. Дані зберігаються рядком на сторінках даних. Навіть якщо інші дані на сторінці не мають значення для вашого запиту, весь цей рядок> сторінка> індекс потрібно прочитати в пам'яті. Я б не сказав, що інші стовпці "скануються" настільки, що сторінки, на яких вони існують, скануються, щоб отримати єдине значення, яке стосується запиту.

Використання прикладу телефонної книги ol: навіть якщо ви просто читаєте телефонні номери, коли ви перегортаєте сторінку, ви перетворюєте прізвище, ім’я, адресу тощо разом із номером телефону.


@ jpmc26 Це може бути гіршим за це, тому що якщо запитувані стовпці є частиною індексу, запит можна подати лише переглянувши індекс. Якщо стовпці не індексуються, вони можуть спричинити завантаження первинного запису та навіть вторинні записи для типів таблиці / стовпців, що не перетискаються.
Крістофер Шульц

12

Це залежить від структури таблиці та наявних індексів.

  • Випадок A: загальна таблиця (рядок), без індексу (order_value).

    Єдиний можливий план виконання - прочитати всю таблицю (що, звичайно, сильно відрізняється, коли це 2 проти 200 стовпців, так що декілька проти декількох тисяч байт в ширину).

  • Випадок B: Загальна таблиця, є індекс (order_value)або деякі інші індекси, що включають цей стовпець.

    Зараз є кращий план, скануйте весь індекс (один з них) - це, звичайно, набагато вужче, ніж уся таблиця, всього кілька байтів. Що не має значення, якщо таблиця має 2 або 200 стовпців. Сканується лише індекс.

  • Випадок С: Це таблиця стовпців.

    Як випливає з назви, структура цих таблиць орієнтована на колонки, а не на рядки. Не потрібно жодного індексу, сама конструкція таблиці підходить для читання цілих стовпців.


Мої знання в цьому питанні трохи зелені. Найбільш звичайно (скажімо, типова база даних SQL Server) мати таблиці зберігання рядків, правда? Чому всю таблицю слід сканувати, якщо потрібно повернути лише один стовпець / поле? Це просто притаманне дизайну столових магазинів?
користувач45867

@ user45867 так, дані зберігаються в рядках (за винятком деяких дуже великих стовпців, які зберігаються зовні). Коли SQL Server читає з диска, він читає цілими блоками, він не може читати лише ту частину, яка містить один стовпець.
ypercubeᵀᴹ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.