Bir tablonun tanımındaki sütunların sırası önemli midir?


35

Bir tablo tanımlarken, sütunları mantıksal gruplar halinde ve grupların kendilerini amaçlarına göre sıralamak yararlı olacaktır. Bir tablodaki sütunların mantıksal sıralaması, geliştiriciye anlam taşır ve iyi bir stil elemanıdır.

Bu temiz.

Ancak net olmayan, bir tablodaki sütunların mantıksal sıralamasının, depolama katmanındaki fiziksel sıralamasını etkileyip etkilemeyeceği veya birinin ilgilenebileceği başka bir etkiye sahip olup olmadığıdır.

Tarz üzerindeki etkinin yanı sıra, sütun düzeni hiç önemli mi?

Stack Overflow'ta bununla ilgili bir soru var , ancak yetkili bir cevaptan yoksun.

Yanıtlar:


23

Bir tablodaki sütunların mantıksal sıralaması, depolama katmanındaki fiziksel sıralarını etkiliyor mu? Evet.

Önemli olup olmaması, (henüz) cevaplayamadığım farklı bir konudur.

Bir kaydın anatomisi üzerine Paul Randal'dan sıkça bağlanan makalede anlatılana benzer şekilde , DBCC IND ile basit iki sütun tablosuna bakalım:

SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;

USE master;
GO

IF DATABASEPROPERTY (N'RowStructure', 'Version') > 0 DROP DATABASE RowStructure;
GO

CREATE DATABASE RowStructure;
GO

USE RowStructure;
GO

CREATE TABLE FixedLengthOrder
(
    c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
    , c2 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
    , c3 CHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL  
);
GO

INSERT FixedLengthOrder DEFAULT VALUES;
GO

DBCC IND ('RowStructure', 'FixedLengthOrder', 1);
GO

DBCC IND çıkışı

Yukarıdaki çıktı, 89. sayfaya bakmamız gerektiğini gösteriyor:

DBCC TRACEON (3604);
GO
DBCC PAGE ('RowStructure', 1, 89, 3);
GO

DBCC PAGE’nin çıktısında, c2’nin before B’den önce “A” karakteriyle doldurulmuş olduğunu görüyoruz:

Memory Dump @0x000000000D25A060

0000000000000000:   10001c00 01000000 41414141 41414141 †........AAAAAAAA
0000000000000010:   41414242 42424242 42424242 030000††††AABBBBBBBBBB...

Ve bunun nedeni, RowStructure.mdfbir hex editörüyle bust açalım ve 'A' dizesinin 'B' dizesini önceden aldığını onayla:

AAAAAAAAAA

Şimdi testi tekrarlayın, ancak 'B' karakterlerini c1'e ve 'A' karakterlerini c2'ye yerleştirerek dizelerin sırasını ters çevirin:

CREATE TABLE FixedLengthOrder
(
    c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
    , c2 CHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL
    , c3 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL  
);
GO

Bu kez DBCC PAGE çıkışımız farklıdır ve ilk önce 'B' dizgisi görünür:

Memory Dump @0x000000000FC2A060

0000000000000000:   10001c00 01000000 42424242 42424242 †........BBBBBBBB 
0000000000000010:   42424141 41414141 41414141 030000††††BBAAAAAAAAAA... 

Yine, sadece kıkırdamalar için, veri dosyasının onaltılık dökümünü kontrol edelim:

bbbbbbbbbb

Olarak bir Record anatomisi açıklar, bir kaydın sabit ve değişken uzunluk sütun farklı bloklar halinde saklanır. Mantıksal olarak serpiştirme sabit ve değişken sütun türlerinin fiziksel kayıt üzerinde hiçbir etkisi yoktur. Ancak, her blokta sütunlarınızın sırası veri dosyasındaki bayt sırasına eşlenir.

CREATE TABLE FixedAndVariableColumns
(
    c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
    , c2 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
    , c3 VARCHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL  
    , c4 CHAR(10) DEFAULT REPLICATE('C', 10) NOT NULL
    , c5 VARCHAR(10) DEFAULT REPLICATE('D', 10) NOT NULL
    , c6 CHAR(10) DEFAULT REPLICATE('E', 10) NOT NULL  
);
GO

Memory Dump @0x000000000E07C060

0000000000000000:   30002600 01000000 41414141 41414141 0.&.....AAAAAAAA 
0000000000000010:   41414343 43434343 43434343 45454545 AACCCCCCCCCCEEEE 
0000000000000020:   45454545 45450600 00020039 00430042 EEEEEE.....9.C.B 
0000000000000030:   42424242 42424242 42444444 44444444 BBBBBBBBBDDDDDDD 
0000000000000040:   444444†††††††††††††††††††††††††††††††DDD

Ayrıca bakınız:

Sütun düzeni önemli değil… genel olarak, ancak - BT DEPENDS!


+1 katılıyorum. Her bölümde, başlangıçta sütunların sırasının ilk önce CREATE TABLEifadeye uygun olduğunu gördüm (CI anahtar sütunlarının bu bölümde ilk gelmesi dışında). Veri ALTER COLUMNtürlerini / sütun uzunluklarını değiştirirse, sütunların sırası değişebilir . Aklıma gelebilecek tek küçük durum değişken uzunluk bölümünün sonunda boş dize veya NULL olan sütunların sütun ofset dizisinde hiç yer almamasıdır (2008 iç kitabında Kalen Delaney tarafından gösterilmiştir)
Martin Smith

1
Köşe sıralaması nadir görülen köşe kasalarında önemli olabilir. Örneğin, 3 sütun A, B ve C olan bir tablonuz varsa, her 3kb bayt uzunluğundadır. SQL Server sayfaları 8 kb'dir, bu nedenle Csığmaz ve kendi genişletilmiş sayfasına gider. Bu yüzden select A, BYourTable` sayfanın okuduğunun sadece yarısını gerektirir select A, C from YourTable.
Andomar

"Whether it matters or not is a different issue that I can't answer (yet).": Sütunların sırası performansı önemli ölçüde etkileyebilir. Ayrıca, hataları bile etkileyebilir! Bunu kontrol et - Demo 2 sanırım daha iyi gösteriyor
Ronen Ariely

@RonenAriely İlginç bir örnek, ancak orijinal soru bağlamında bir şekilde var olduğu açık. Daha sonra sütunu bıraktığınızda sütun sırasının nasıl bir etkisi olduğunu göstermiş oluyorsunuz. Daha önce hangi sütunları bırakacağımı öngören bir masa tasarladığımı sanmıyorum.
Mark Storey-Smith

Merhaba @ MarkStorey-Smith. (1) Bir mimar olarak, iyi tasarım ve Harika tasarım arasındaki farklılığın her zaman iyi tasarımın mevcut ihtiyaçları sağladığını, Büyük tasarım ise henüz bilinmeyen gelecekteki ihtiyaçları sağladığını açıklarım. (2) Sorunun cevabı saf EVET. Cevabın uygulanması OP'ye ve her birimize kalmış. Bu tartışmanın kapsamı dışındadır, ancak bu konuyu tartışma için açabiliriz. Ancak stackoverflow forumları ailesinde değil, çünkü arabirim gerçek bir tartışmaya izin vermiyor, ancak yanıtlara yalnızca tek bir zayıf kısa metin satırı ekliyor
Ronen Ariely

7

Kümelenmiş bir dizin tanımlamazsanız, bir yığın tablosu elde edersiniz. Bir yığın tablosu için, verileri okurken her zaman tarama yapıyor olacaksınız ve böylece tüm satırlar okunacak ve bu da sütunların sıralamasını bir noktaya getirecektir.

Kümelenmiş bir dizini tanımladığınız anda veriler, belirttiğiniz sütunların fiziksel sırasına uyacak şekilde fiziksel olarak yeniden düzenlenir - ve bu noktada, fiziksel sıra önem kazanır. Fiziksel düzen, kullandığınız tahminlere göre arayan operatörün uygunluğunu belirleyen şeydir.

Herhangi bir yerde okuduğumu hatırlayamasam da, SQL Server'ın yığınlar için sütunların fiziksel sırasını garanti etmediğini varsayarsak, dizinler için de garanti altına alınacağını varsayardım. Sorunuzu cevaplamak için, hayır, tanımdaki sütunların sırası, verileri okurken farketmeyeceklerinden önemli olmamalıdır (bunun yalnızca yığınlar - dizinler için farklı bir konu olduğunu unutmayın).

Güncelleme
Aslında iki soru soruyorsunuz - "bir tablodaki sütunların mantıksal sıralamasının depolama katmanındaki fiziksel sıralamasını etkileyip etkilemediği" hayır. Meta veriler tarafından tanımlanan mantıksal düzen, fiziksel olanla aynı sırada olmak zorunda değildir. Topladığım bir cevap, CREATE TABLE'daki mantıksal düzenin yaratma konusunda aynı fiziksel düzende olup olmadığını - bilmiyorum, yığınlar için - yukarıdaki uyarıya rağmen.


2

Gördüklerime ve SQL Server'daki sütunların sıralamasını okuduğumuza göre farketmez. Depolama motoru, CREATE TABLE ifadesinde nasıl belirtildiklerine bakılmaksızın satıra sütunlar yerleştirir. Olduğu söyleniyor, önemli olduğu bazı çok izole kenar davaları olduğuna eminim ama bence bunlara tek bir kesin cevap almakta zorlanacaksınız. Paul Randal'ın " Depolama Motorunun İçinde"blog kategorileri, depolama motorunun nasıl çalıştığımla ilgili tüm ayrıntılar için en iyi kaynaktır. Tüm kullanım durumlarına karşı depolamanın çalıştığı ve matrisin çeşitli şekillerini incelemeniz gerekeceğini düşünüyorum. Siparişin önemli olacağı kenar kasaları bulmak için Durumum için geçerli olan belirli bir kenar çantası belirtilmediği sürece, sütunları mantıksal olarak CREATE TABLE'ımda sipariş ediyorum.


1

Ne demek istediğini anlıyorum. Tasarım perspektifinden şuna benzeyen bir tablo:

**EMPLOYEES**
EmployeeID
FirstName
LastName
Birthday
SSN 

şuna benzeyen bir tablodan daha iyidir:

**EMPLOYEES**
LastName
EmployeeID
SSN 
Birthday
FirstName

Ancak, böyle bir tsql verirseniz, Veritabanı motoru gerçekten mantıksal sütun sıranızı pek önemsemez:

SELECT FirstName, LastName, SSN FROM Employees

Motor, FirstName listesinin diskte nerede depolandığını bilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.