Index Seek vs Index Scan


64

Yavaş çalışan bir sorgu yürütme planına baktığımda, bazı düğümlerin indeks arayışı ve bazılarının indeks taraması olduğunu fark ettim.

İndeks arama ve indeks taraması arasındaki fark nedir?

Hangisi daha iyi performans gösterir?

SQL, birini diğerinden nasıl seçer?

Bunun 3 soru olduğunun farkındayım, ancak ilkini cevaplamanın diğerlerini açıklayacağını düşünüyorum.


6
Index-luke kullanımıyla ilgili güzel bir referansınız var .
Marian,

7
Tüm taramalar kötü değildir - bazen sorguyu karşılamak için en etkili yoldur. Ayrıca, tüm aramaların aranmadığını unutmayın - çoğu zaman aslında aralık taramalarıdır ve arama yalnızca aralığın nasıl başladığını gösterir.
Aaron Bertrand

@AaronBertrand, ancak aralığın başına gelir ve okursa, temelde verilere ihtiyaç duyduğunuz anlamına gelir. Ayrıca, aralığın sonunu istiyor.
George Polevoy

Yanıtlar:


76

Kısa versiyon: arama daha iyidir

Daha az kısa versiyon: arama genellikle daha iyidir, ancak çok fazla sayıda arama yapılır (örneğin kötü bir şekilde ilişkilendirilmiş alt sorgularla kötü sorgu tasarımından kaynaklanır veya bir imleç işleminde veya başka bir döngüde çok fazla sorgu yaptığınız için); özellikle sorgunuz etkilenen tablodaki satırların çoğundan veri döndürmeyi başlatabilirse, tarayın.

Performansın etkilerini tam olarak anlamak için veri bulma işlemlerinde tüm ailenin korunmasına yardımcı olur.

Tablo Taramaları: Sorgunuzla ilgili hiç bir indeks bulunmadığında, planlayıcı her satırın bakıldığı anlamına gelen bir tablo taraması kullanmak zorunda kalır. Bu, tablonun verileriyle ilgili her sayfanın genellikle en kötü durum olan diskten okunmasına neden olabilir. Bazı sorgular için yararlı bir dizin mevcut olsa bile bir tablo taraması kullanacağını unutmayın - bunun nedeni genellikle tablodaki verilerin çok küçük olmasıdır; Dizinin seçicilik ölçüsünün iyi olduğu varsayılarak, veriler büyüdükçe değişmeyi planlayın).

Satır Aramaları İçinde Dizin Taramaları: Bir arama için doğrudan kullanılabilecek hiçbir indeks bulunmaz, ancak doğru sütunları içeren bir indeks bulunur, bir indeks taraması kullanılabilir. Örneğin, column1, col2, col3 üzerinde bir dizine sahip 20 sütunlu büyük bir tablonuz varsa ve bu sayıyı yayınlarsanız, SELECT col4 FROM exampletable WHERE col2=616bu durumda dizini sorgulamaya col2taramak tüm tablonun taranmasından daha iyidir. Eşleşen satırlar bulunduğunda, veri sayfalarının çıktı (veya daha fazla birleştirme) için col4'ü almak için okunması gerekir; bu, sorgu planlarında gördüğünüzde "yer imi araması" aşamasıdır.

Dizin Aramaları Olmadan Dizin Taramaları: Yukarıdaki örnek SELECT col1, col2, col3 FROM exampletable WHERE col2=616öyleyse, veri sayfalarını okumak için ek bir çabaya gerek kalmaz: bir kez dizin satırları eşleşmesi col2=616bulunduğunda istenen tüm veriler bilinir. Bu yüzden bazen asla aranmayacak sütunlar görüyorsunuz, ancak endekslerin sonuna eklenmesi için çıktı isteniyor - satır aramalarını kaydedebiliyor. Dizine bu nedenle yalnızca bu nedenle sütunları eklerken INCLUDE, motora bu sütunları temel alarak sorgulamak için dizin düzenini optimize etmesinin gerekmediğini söylemek için yan tümce ekleyin (bu, bu sütunlara yapılan güncellemeleri hızlandırabilir). . Dizin taramaları, süzgeç cümlecikleri olmayan sorgulardan da kaynaklanabilir: SELECT col2 FROM exampletablebu örnek dizini tablo sayfaları yerine tarar.

Dizin Aradı (satır aramaları olsun veya olmasın) : Bir arayışta endeksin tamamı dikkate alınmaz. Sorgu için SELECT * FROM exampletable WHERE c1 BETWEEN 1234 AND 4567sorgu motoru üzerinde endeksinde bir ağaç bazlı arama yaparak maç olacak ilk satırı bulabilirsiniz c1bunun bir sorgu ile aynıdır (aralığının sonuna kadar gelene kadar o zaman sırayla endeksi gezinebilirsiniz çünkü c1=1234bir =operasyon için bile şartla eşleşen birçok satır olabilir ). Bu, indeks (veya tablodaki) her sayfa yerine yalnızca ilgili dizin sayfalarının (artı ilk arama için gerekli birkaç sayfa) okunması gerektiği anlamına gelir.

Kümelenmiş Dizinler: Kümelenmiş bir dizin ile tablo verileri, ayrı bir yığın yapısında olmak yerine o dizinin yaprak düğümlerinde depolanır. Bu [sizin gibi off-sayfa verilerini yoksa ne ihtiyaç vardır sütunlar olursa olsun o dizini kullanarak satırları bulduktan sonra herhangi bir ekstra satır aramalarını sağlanması gerekir asla anlamına gelir TEXTsütun veya VARCHAR(MAX)uzun veri içeren sütunlar].

Sadece bu nedenden dolayı bir kümelenmiş bir dizin olabilir [1] , kümelenmiş dizin olan yerine ayrı yığın yapısına sahip senin masa, kullandığınız takdirde bir [2] maksimum kazanç elde etmek için dikkatlice nereye koyduğunuzu seçti.

Ayrıca, kümelenmiş dizinin, tablonun "kümelenme anahtarı" olduğundan ve tablodaki kümelenmemiş her dizinde bulunduğundan, bu nedenle geniş kümelenmiş bir dizinin genellikle iyi bir fikir olmadığını unutmayın.

[1] Aslında, masadaki her sütunu kaplayan ya da içeren kümelenmemiş dizinleri tanımlayarak etkili bir şekilde kümelenmiş indekslere sahip olabilirsiniz , ancak bunun boşa harcanması muhtemeldir; gerçekten ihtiyacın var.

Dediğimde "Bir kümelenmiş bir dizin kullanırsanız" [2], genellikle önerilir unutmayın do do Her masada bir tane var. Tüm kurallara uymayan kurallar, toplu kesici uçlar dışında çok az şey gören tablolar ve sıralanmamış okumaların (belki de ETL işlemleri için hazırlama tabloları) en yaygın sayaç örneği olduğu gibi istisnalar vardır.

Ek nokta: Eksik Taramalar:

Sorgunun geri kalan kısmına bağlı olarak, bir tablo / dizin taramasının aslında tüm tabloyu taramayabileceğini hatırlatmak önemlidir - eğer mantık sorgu planının erken iptal edilmesine neden olabilirse. Bunun en basit örneği şudur SELECT TOP(1) * FROM HugeTable: Bunun için sorgu planına bakarsanız, taramadan yalnızca bir satırın döndüğünü SET STATISTICS IO ON; SELECT TOP(1) * FROM HugeTablegöreceksiniz ve GÇ istatistiklerini ( ) izlerseniz ( ) sadece çok küçük bir sayı okuduğunu görürsünüz Sayfaların (belki sadece bir).

Aynı şey, a WHEREveya JOIN ... ONyan tümcesinin belirtisi, eğer verileri ise kaynak olan taramayla aynı anda çalıştırılabilirse gerçekleşebilir. Sorgu planlayıcısı / koşucu bazen bu şekilde tarama erken sonlandırılmasını sağlamak için veri kaynakları doğru geri yüklemler iterek hakkında çok zeki olabilir ki (ve bazen sen bunu yapmak yardım etmek sorguları yeniden düzenleme içinde zeki olabilir ki!). İken veri sağdan sola standart sorgu planı ekranda oklar göre akar, mantık soldan sağa çalışır ve bir sonraki başlamadan önce her adım (sağdan sola) ille tamamlanma çalıştırılan değil. Yukarıdaki basit örnekte, sorgu planındaki her bir bloğa bir aracı olarak bakarsanız, SELECTaracıdan TOPbir satır sorar;TABLE SCANbiri için SELECTajan , o zaman ajan diğerini sorar, ancak TOPajan masa okuyucuyu sormaya bile zahmet etmenin gerekmediğini bilir, SELECTajan "artık ilgili değildir" cevabını alır ve tüm işlerin yapıldığını bilir. Birçok işlemleri bir tablo / dizin tarama gerçekten daha karmaşık örneklerde sık sık elbette optimizasyonu bu tür bloke etmez her satır okumak, ancak herhangi bir tarama pahalı bir işlem olmalıdır sonucuna atlamak için dikkatli olun.


6

Genelde, aramalar iyidir, taramalar kötüdür.

Sorgunun, dizini etkin bir şekilde kullanabildiği ve ihtiyaç duyduğu satırları bulmak için kullanabileceği yerlerdir.

Taramalar, sorgunun ihtiyacı olanı bulmaya çalışırken tüm indekse bakmakta olduğu yerdir.

SQL nasıl seçilir? Sorgu iyileştiricinin içindekilerde, karar, sorgunuza ve kullanılabilir dizinlere ve bu dizinlerle ilişkili istatistiksel bilgilere dayanarak verilir.

Burada ilgisini çekebilecek birkaç kitap var - Her ikisi de http://www.red-gate.com/community/books/ adresindeki Red-Gate kitabevinden

  • Grant Fritchey'den SQL Server Yürütme Planları
  • Benjamin Nevarez'ın Sorgu İyileştiricisi İçinde
  • Holger Schmeling'den SQL Sunucu İstatistikleri

7
Aynı plan için tek bir masa taraması iyidir, bir milyonu kötüdür. Yani ilk ifaden tamamen doğru değil.
Marian,

Aslında, her biri kendi endeksini taramak ve dizin taramak için kullanmaktadır, altta yatan tablo ve sorguların içeriği OLMADAN birinin diğerinden daha iyi olduğunu söyleyemezsiniz. Bir tablonun istatistiği hatalıysa, çoğu zaman bir indeks taraması sırasında yanlışlıkla indeks taraması yapılır ve bunun tersi seçildiğinde, uygulama planı alt-optimal olarak ortaya çıkabilir.
jyao

5

Konuyu kazmak istiyorsanız, çok yararlı bir kitap (en azından benim için), Grant Fritchey tarafından sunulan SQL Server Yürütme Planları, burada RedGate'de serbestçe kullanılabilir .

Gibi bir sorunuz varsa

SELECT *
FROM myTable

SQL Server, muhtemelen gerekli sonuçları görüntülemek için tüm satırları geçmesi gerektiğinden bir İndeks taraması kullanacaktır.

Aksine,

SELECT *
FROM myTable
WHERE myID = 1

Endeks arayışıyla sonuçlanacaktır. SQL Server , myID endeksinin B-tree yapısını kullanacak ve doğru satırı elde etmek çok daha hızlı olacaktır.


"Kesinlikle" ile aynı fikirdeyim mi bilmiyorum - bir dizin lider kimliğimin myID'sine sahip olsa bile, bir arama en uygun cevap olmayabilir (benzersiz olup olmadığı gibi pek çok şeye bağlı olarak olabilir) Müşteriler tablosunda doğrudur, ancak siparişler tablosunda customerID için değildir, kaç sütunun kapsanması gerekir, ancak dizinde yer almaz, vb.).
Aaron Bertrand

Bu cevabın gerçekten sorulan soruları kapsadığını sanmıyorum.
Zero3

5

Diğerleri arama ve tarama arasındaki farkları yeterince iyi tanımlamışlardır. Bu örnekte, sorgunuzun kendisi ve yürütme planlayıcısı, her bir bölümdeki sorgu için hangi değerlerin tahmin (filtre) olarak kullanıldığını görmeniz için gereken bilgileri size vermelidir. Genelde, yabancı anahtarlara her zaman kümelenmemiş dizinler eklemek iyi bir uygulamadır ve program kodundaki kullanım durumlarına bağlı olarak, ek çok sütunlu dizinler veya dahil edilen sütun dizinleri oluşturmak isteyebilirsiniz. Burada sunulan terminoloji ile bir google araması, her biri için örnekler üzerinde iyi sonuçlar verecektir.

Ancak bir örnek olarak, kodunuzun verilen filtrelerde Sütun A ve Sütun B'yi sorguladığını, ancak Sütun C ve Sütun E'nin değerlerini de döndürmek istediğinizi varsayalım. Sütun C ve E içeren seçenek. Bu şekilde tek bir dizin araması, aynı satırdaki diğer değerleri (C ve E) almak için bir arama yapmaya gerek olmadığından ihtiyacınız olan her şeyi döndürür.

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.