SQL'de cümleciklerin sıralaması önemli mi?


121

Diyelim ki PEOPLE3 sütun içeren bir tablom var ID, LastName, FirstName, bu sütunların hiçbiri indekslenmemiş.
LastNamedaha benzersizdir ve FirstNamedaha az benzersizdir.

2 arama yaparsam:

select * from PEOPLE where FirstName="F" and LastName="L" 
select * from PEOPLE where LastName="L" and FirstName="F"

Benim inancım ikincisinin daha hızlı olması çünkü cümlecikte daha benzersiz ölçüt ( LastName) ilk sırada gelir whereve kayıtlar daha verimli bir şekilde ortadan kaldırılır. Optimize edicinin ilk sql'yi optimize edecek kadar akıllı olduğunu düşünmüyorum.

Anladığım doğru mu?


8
Hayır, bu sıra önemli değil - herhangi bir düzgün sorgu iyileştirici tüm WHERE maddelerine bakacak ve bu sorguyu karşılamanın en verimli yolunu bulacaktır
marc_s

3
Bu iki ifadeyi çalıştırdığınızda gözlemleriniz nelerdi? Uygulama planları neye benziyordu?
Conrad Frix

3
Belirli bir RDBMS'den mi bahsediyorsunuz? Gerçekten de farklılıklar var.
Bjoern

6
Muhtemel SQL
Conrad Frix

Yanıtlar:


101

Hayır, bu sıra önemli değil (veya en azından: önemli olmamalı).

Herhangi bir düzgün sorgu iyileştiricisi , cümlenin tüm bölümlerine bakacak ve WHEREbu sorguyu tatmin etmenin en verimli yolunu bulacaktır .

SQL Server sorgu iyileştiricisinin uygun bir dizin seçeceğini biliyorum - iki koşulunuz hangi sırada olursa olsun. Diğer RDBMS'lerin de benzer stratejileri olacağını varsayıyorum.

Önemli olan bunun için uygun bir dizininiz olup olmadığıdır!

SQL Server söz konusu olduğunda, şunlara sahipseniz büyük olasılıkla bir dizin kullanacaktır:

  • bir dizin (LastName, FirstName)
  • bir dizin (FirstName, LastName)
  • sadece (LastName)veya sadece (FirstName)(veya her ikisi) üzerine bir dizin

Öte yandan - yine SQL Server için - Kullanmak eğer SELECT *kapmak için tüm bir tablo sütunlarından ve tablo oldukça küçük, daha sonra sorgu iyileştirici bir masayı (veya kümelenmiş dizin) yapacak iyi bir şans taramak yerine kullanarak var bir dizin (çünkü diğer tüm sütunları almak için tam veri sayfasına arama çok hızlı bir şekilde çok pahalı hale gelir).


Dizin yoksa, verilere bağlı olarak işlem doğru olabilir. Kurs, indeksler olmadan böyle bir şey yapmak garip bir karar olurdu ...
Tony Hopkinson

@TonyHopkinson: Sanmıyorum - dizinler olmasa bile herhangi bir fark olduğundan şüpheliyim. Sonuçta: indeksler olmadan, RDBMS tam bir tablo taramasından başka ne yapabilir, gerçekten ??
marc_s

2
SQL sunucusuyla ilgili ilginç yan not, görünüşe göre, tahminler
Justin Swartsel

3
Garip bir şey, bir sorgunun ilk yürütülmesi için bir WHERE cümlesindeki koşulların sırasının ÖNEMLİDİR! İki koşulum vardı, şöyle bir şey: WHERE T1.col_1/T2.col_2 > 10 AND T2.col_2 <> 0ve bir DIVIDE BY 0hata aldım . Sırayı değiştirdikten sonra, sorgu başarılı bir şekilde yürütüldü. Sonra sırayı geri değiştirdim, böylece hatayı tekrar almayı bekliyordum, ancak bu sefer işe yaradı! Sonunda, ilk çalıştırmada yürütme planı oluşturulana kadar sıranın önemli olduğu sonucuna vardım. 'önemli değil' çünkü optimize edici / yürütme planı bununla ilgilenecek
Radu Gheorghiu

1
"... veya en azından: önemli olmamalı" demeni beğendim - tamamen katılıyorum. Bazen ne yazık ki önemli. SQL'in optimize edicinin işleyemeyeceği kadar karmaşık olduğu ve sütun sırası ve tablo birleştirme sırası gibi şeylerin fark yarattığı durumlar gördüm. RDBMS'ye, SQL deyiminin karmaşıklığına ve hatta sürüme bağlıdır. Çok karmaşık SQL, kötü optimize edici kararlarına veya optimize edici kodunda sabit kodlanmış varsayılanların kullanımına neden olabilir.
Victor Di Leo

19

WHERE cümlelerinin sırası, SQL standardına uyan bir veritabanında bir fark yaratmamalıdır. Çoğu veritabanında değerlendirme sırası garanti edilmez.

SQL'in sıralamayı önemsediğini düşünmeyin. Aşağıdaki, SQL Server'da bir hata oluşturur:

select *
from INFORMATION_SCHEMA.TABLES
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0

İlk olarak bu cümlenin ilk bölümü çalıştırılırsa, yalnızca sayısal tablo adları tamsayı olarak dönüştürülür. Ancak, SQL Server'ın (diğer veritabanlarında olduğu gibi) WHERE deyimindeki cümle sırasını önemsemediğine dair net bir örnek sağlayarak başarısız olur.


Hataya neden olan bu sorgunun, WHERE tahmin değerlendirmesinin sırası ile ne ilgisi var?
Jim

7
@Jim ISNUMERIC(table_name) = 1İlk önce değerlendirildiyse, o CASTzaman yalnızca sayısal tablo adları için çağrılır. Ancak önce CASTdeğerlendirilmediği için sayısal olmayan tablo adları için de değerlendirilir ve hata mesajına neden olur.
hibbelig

2
Mükemmel açıklama
neeohw

Koşulları değiştirmenin SQL sunucusunun bunları başka şekilde ele almasına neden olup olmayacağını kontrol ettiğimden emin olmak için, ancak her iki şekilde de başarısız oluyor. Sanırım bu iki şeyden biri anlamına gelebilir: (1) Olabildiği kadar optimize etmiyor veya (2) Bu bir derleme zamanı hatası ve SQL herhangi bir şeyi karşılaştırmayı denemeye bile başlamıyor, ön durumu kurtarıyor. Benim tahminim bu nr. 2.
Louis Somers

9

ANSI SQL Taslak 2003 5WD-01-Framework-2003-09.pdf

6.3.3.3 Kural değerlendirme sırası

...

Önceliğin Biçimler veya parantezlerle belirlenmediği durumlarda, ifadelerin etkili değerlendirmesi genellikle soldan sağa gerçekleştirilir. Bununla birlikte, ifadelerin gerçekten soldan sağa değerlendirilip değerlendirilmeyeceği, özellikle işlenenler veya işleçler koşulların ortaya çıkmasına neden olduğunda veya ifadelerin sonuçlarının ifadenin tüm bölümleri tam olarak değerlendirilmeden belirlenip belirlenemeyeceği uygulamaya bağlıdır.

buradan kopyalandı


2

Hayır, tüm RDBM'ler öncelikle sorguyu analiz ederek başlar ve where cümlenizi yeniden sıralayarak onu optimize eder.

Hangi RDBM'yi kullandığınıza bağlı olarak, analizin sonucunu görüntüleyebilirsiniz (örneğin oracle'da açıklama planı arayın)

M.


Bunu indekslere göre yapar. Yani içerik açısından dolaylı.
Tony Hopkinson

1

Orijinal OP beyanı

Benim inancım, ikincisinin daha hızlı olması çünkü daha benzersiz kriter (LastName), where cümlesinde ilk sırada gelir ve kayıtlar daha verimli bir şekilde ortadan kaldırılır. İyileştiricinin> ilk sql'yi optimize edecek kadar akıllı olduğunu düşünmüyorum.

Sanırım bunu, dizinleri oluştururken sütunların sırasını seçmekle karıştırıyorsunuz; burada daha seçici sütunları, en seçici olan ikinci sütundan daha önce koymak zorunda kalıyorsunuz vb.

BTW, yukarıdaki iki sorgu için SQL sunucu optimizasyonu herhangi bir optimizasyon yapmayacaktır ancak planın toplam maliyeti paralellik eşik maliyetinden düşük olduğu sürece Trivila planını kullanacaktır.


0

İsimlerin indekslenmediğini varsayarak, gittiği kadarıyla doğrudur. Ancak farklı veriler yanlış olur. Her seferinde farklı olabilecek, bunu hangi şekilde yapacağını bulmak için, DBMS'nin her sütun için ayrı bir sayım sorgusu çalıştırması ve sayıları karşılaştırması gerekir, bu sadece omuz silkip devam etmekten daha pahalıya mal olur.

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.