Le colonne non pertinenti influiscono sul tempo di query delle istruzioni selezionate?


10

Sono solo curioso.

Supponi di avere una tabella con 1 milione di record / righe.

select order_value from store.orders

Fa differenza se quella tabella ha 1 campo, 2 campi o 100 campi, nel tempo effettivo della query? Intendo tutti i campi diversi da "order_value".

In questo momento sto trasferendo i dati in un data warehouse. A volte scarico campi nella tabella che "potrebbero essere utilizzati in futuro, un giorno" - ma non vengono interrogati in questo momento, da nulla. Questi campi "estranei" inciderebbero su determinate istruzioni che non le includono, direttamente o indirettamente (no * intendo)?


Ci sono tonnellate di informazioni su questo disponibili sul web. La chiave sta ottenendo le informazioni più recenti al variare della tecnologia. Quello che stai chiedendo è così dipendente dalla tua configurazione particolare che non è possibile dare una risposta molto buona. Un punto chiave da ricordare è che mentre ci spostiamo su SSD, molte cose che un tempo erano molto importanti per le prestazioni non sono più il caso.
Joe,

Risposte:


10

Questo dipende davvero da indici e tipi di dati.

Utilizzando il database Stack Overflow come esempio, ecco come appare la tabella Users:

NOCCIOLINE

Ha un PK / CX nella colonna Id. Quindi è l'insieme dei dati della tabella ordinati per ID.

Con questo come unico indice, SQL deve leggere l'intera cosa (senza le colonne LOB) se non è già presente.

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

SET STATISTICS TIME, IO ON 

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

Il tempo delle statistiche e il profilo io si presentano così:

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.

Se aggiungo un ulteriore indice non cluster solo su Id

CREATE INDEX ix_whatever ON dbo.Users (Id)

Ora ho un indice molto più piccolo che soddisfa la mia domanda.

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

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

Il profilo qui:

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.

Siamo in grado di fare molte meno letture e risparmiare un po 'di tempo sulla CPU.

Senza ulteriori informazioni sulla definizione della tabella, non posso davvero provare a riprodurre ciò che stai cercando di misurare meglio.

Ma stai dicendo che a meno che non ci sia un indice specifico su quella colonna solitaria, anche le altre colonne / campi verranno scansionate? Questo è solo uno svantaggio inerente al design delle tabelle del rowstore? Perché i campi irrilevanti dovrebbero essere scansionati?

Sì, questo è specifico per le tabelle del rowstore. I dati vengono archiviati dalla riga nelle pagine di dati. Anche se altri dati sulla pagina sono irrilevanti per la tua query, l'intera riga> pagina> indice deve essere letta in memoria. Non direi che le altre colonne sono "scansionate" tanto quanto le pagine su cui esistono sono scansionate per recuperare il singolo valore su di esse rilevante per la query.

Usando l'esempio della vecchia rubrica: anche se stai solo leggendo i numeri di telefono, quando giri la pagina, stai girando il cognome, il nome, l'indirizzo, ecc. Insieme al numero di telefono.


@ jpmc26 Può andare peggio di così, perché se le colonne richieste fanno tutte parte di un indice, la query può essere servita semplicemente guardando l'indice. Se le colonne non sono indicizzate, possono causare il caricamento del record primario e persino dei record secondari per i tipi di tabella / colonna non raggruppati.
Christopher Schultz,

12

Dipende dalla struttura della tabella e dagli indici disponibili.

  • Caso A: tabella comune (rowstore), nessun indice attivo (order_value).

    L'unico piano di esecuzione possibile è leggere l'intera tabella (che è ovviamente molto diversa quando si tratta di 2 vs 200 colonne, quindi larga qualche poche migliaia di byte).

  • Caso B: tabella comune, esiste un indice su (order_value)o altri indici che includono quella colonna.

    Ora c'è un piano migliore, scansiona l'intero indice (uno di loro) - che è ovviamente molto più ristretto dell'intera tabella, solo pochi byte. Il che rende irrilevante se la tabella ha 2 o 200 colonne. Viene scansionato solo l'indice.

  • Caso C: è una tabella columnstore.

    Come suggerisce il nome, la struttura di queste tabelle è orientata alla colonna, non alla riga. Non è necessario alcun indice, il design della tabella stessa è adatto per la lettura di intere colonne.


La mia conoscenza è un po 'verde su questo problema. È più convenzionale (diciamo il tipico database SQL Server) avere tabelle rowstore, giusto? Perché l'intera tabella dovrebbe essere scansionata se fosse necessario restituire solo una colonna / campo? È solo inerente alla progettazione delle tabelle del rowstore?
user45867,

@ user45867 sì, i dati sono archiviati in righe (tranne alcune colonne molto grandi che sono archiviate all'esterno). Quando SQL Server legge dal disco, legge in blocchi interi, non può leggere solo la parte che ha una colonna.
ypercubeᵀᴹ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.