Alakalı olmayan sütunlar, seçili ifadelerin sorgu süresini etkiler mi?


10

Ben sadece merak ediyorum.

Diyelim ki 1 milyon kayıt / sıradan oluşan bir tablonuz var.

select order_value from store.orders

Bu tablonun gerçek sorgu zamanında 1 alanı, 2 alanı veya 100 alanı olması fark eder mi? "Order_value" dışındaki tüm alanları kastediyorum.

Şu anda veriyi bir veri ambarına gönderiyorum. Bazen tarlaları masaya "gelecekte, bir gün kullanılabilecek" döküyorum - ama şu anda hiçbir şey tarafından sorgulanmıyorlar. Bu 'yabancı' alanlar, doğrudan veya dolaylı olarak içermeyen seçme ifadeleri etkiler mi (hayır * demek istediğim)?


Bu konuda internette tonlarca bilgi bulunmaktadır. Anahtar teknoloji değiştikçe en son bilgileri almaktır. Sorduğunuz şey, kurulumunuza o kadar bağımlı ki, çok iyi bir cevap vermek mümkün değil. Hatırlanması gereken kilit nokta, SSD'ye geçtikçe, bir zamanlar performans için çok önemli olan birçok şeyin artık geçerli olmadığıdır.
Joe

Yanıtlar:


10

Bu gerçekten indekslere ve veri türlerine bağlıdır.

Örnek olarak Stack Overflow veritabanı kullanıldığında, Kullanıcılar tablosu şöyle görünür:

FINDIK

Kimlik sütununda bir PK / CX vardır. Yani, Id'ye göre sıralanmış tablo verilerinin tamamıdır.

Tek dizin olarak, SQL zaten yoksa tüm şeyi (LOB sütunlarını sans) belleğe okumak zorundadır.

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

SET STATISTICS TIME, IO ON 

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

İstatistik zamanı ve io profili şöyle görünür:

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.

Sadece kimliğe ek bir kümelenmemiş dizin eklersem

CREATE INDEX ix_whatever ON dbo.Users (Id)

Şimdi benim sorgu tatmin çok daha küçük bir dizin var.

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

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

Buradaki profil:

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.

Çok daha az okuma yapabilir ve biraz CPU zamanından tasarruf edebiliriz.

Tablo tanımınız hakkında daha fazla bilgi olmadan, daha iyi ölçmeye çalıştığınız şeyi çoğaltmaya çalışamıyorum.

Ancak, bu yalnız sütunda belirli bir dizin olmadıkça, diğer sütunların / alanların da taranacağını söylüyorsunuz? Bu yalnızca mağaza mağazalarının tasarımının doğasında var olan bir dezavantaj mıdır? Alakasız alanlar neden taranacak?

Evet, bu satır mağaza tablolarına özgüdür. Veriler satırda veri sayfalarında depolanır. Sayfadaki diğer veriler sorgunuzla alakasız olsa bile, tüm satır> sayfa> dizininin belleğe okunması gerekir. Diğer sütunlar üzerinde var oldukları sayfalar sorgu ile ilgili tek bir değer almak için taranan "taranan" olduğunu söyleyemem.

Ol 'telefon rehberi örneğini kullanarak: sadece telefon numaralarını okuyor olsanız bile, sayfayı çevirirken telefon numarasıyla birlikte soyadı, adı, adresi vb. Çeviriyorsunuz.


@ jpmc26 Bundan daha kötüye gidebilir, çünkü istenen sütunların tümü bir dizinin parçasıysa, sorgu yalnızca dizine bakarak sunulabilir. Sütunlar halinde değil endeksli, bunlar birincil kayıt yüklenmesine neden olabilir ve olmayan custered tablo / sütun türleri için bile ikincil kayıtlar olabilir.
Christopher Schultz

12

Tablo yapısına ve kullanılabilir dizinlere bağlıdır.

  • Durum A: Ortak (rowstore) tablosu, dizin yok (order_value).

    Mümkün olan tek yürütme planı tüm tabloyu okumaktır (2'ye 200 sütun olduğunda elbette çok farklı, bu yüzden birkaç bin birkaç bayt genişliğinde).

  • Durum B: Ortak tablo, (order_value)bu sütunu içeren bir dizin veya bazı diğer dizinler vardır.

    Şimdi daha iyi bir plan var, tüm indeksi (bunlardan biri) tarayın - elbette tüm tablodan çok daha dar, sadece birkaç bayt. Tablonun 2 veya 200 sütunu varsa ilgisiz yapar. Yalnızca dizin taranır.

  • Durum C: Bu bir sütun deposu tablosu.

    Adından da anlaşılacağı gibi, bu tabloların yapısı satır değil satır sütun yönündedir. Herhangi bir dizine gerek yoktur, tablo tasarımının kendisi tüm sütunları okumak için uygundur.


Bu konuda bilgim biraz yeşil. En geleneksel (tipik SQL Server veritabanı) sıra mağaza tabloları var, doğru mu? Yalnızca bir sütun / alanın döndürülmesi gerekiyorsa neden tüm tablo taranacak? Bu yalnızca mağaza mağazalarının tasarımının doğasında var mı?
user45867

@ user45867 evet, veriler satırlar halinde saklanır (dışarıda depolanan çok büyük sütunlar hariç). SQL Server diskten okuduğunda, tüm blokları okur, sadece bir sütunu olan kısmı okuyamaz.
ypercubeᵀᴹ
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.