Yanıtlar:
exists
Anahtar kelime bu şekilde kullanılabilir, ancak gerçekten önlemek sayma için bir yol olarak niyetiyle:
--this statement needs to check the entire table
select count(*) from [table] where ...
--this statement is true as soon as one match is found
exists ( select * from [table] where ... )
Bu, if
koşullu ifadeleriniz olduğunda en kullanışlıdır , çünkü exists
daha hızlı olabilircount
.
En in
iyi, iletilecek statik bir listeniz olduğunda kullanılır:
select * from [table]
where [field] in (1, 2, 3)
Bir in
ifadede bir tablonuz olduğunda, a'yı kullanmak daha mantıklıdır join
, ancak çoğunlukla önemli olmamalıdır. Sorgu iyileştirici aynı planı her iki şekilde de döndürmelidir. Bazı uygulamalarda (çoğunlukla Microsoft SQL Server 2000 gibi daha eski) in
sorgular her zaman iç içe bir birleştirme planı alırken, join
sorgular iç içe, birleştirme veya karmayı uygun şekilde kullanır. Daha modern uygulamalar daha akıllıdır ve in
kullanıldığında bile planı ayarlayabilir .
select * from [table] where [field] in (select [field] from [table2])
ile aynı sonuçları (ve sorgu planını) döndürür select * from [table] join [table2] on [table2].[field] = [table].[field]
.
table
, ikinci döner her şeyi yaparken table
ve table2
. Bazı (çoğunlukla eski) SQL veritabanlarında in
sorgu iç içe birleştirme olarak uygulanırken, join
sorgu iç içe geçmiş, birleştirilebilir, karma, vb.
exists
bir vaka ifadesi içinde kullanılabilir, bu yüzden de bu şekilde kullanışlı olabilir yaniselect case when exists (select 1 from emp where salary > 1000) then 1 else 0 end as sal_over_1000
EXISTS
bir sorgunun sonuç döndürüp döndürmediğini size bildirir. Örneğin:
SELECT *
FROM Orders o
WHERE EXISTS (
SELECT *
FROM Products p
WHERE p.ProductNumber = o.ProductNumber)
IN
, bir değeri birkaç ile karşılaştırmak için kullanılır ve aşağıdaki gibi değişmez değerleri kullanabilir:
SELECT *
FROM Orders
WHERE ProductNumber IN (1, 10, 100)
Ayrıca, IN
yan tümce ile sorgu sonuçlarını aşağıdaki gibi kullanabilirsiniz:
SELECT *
FROM Orders
WHERE ProductNumber IN (
SELECT ProductNumber
FROM Products
WHERE ProductInventoryQuantity > 0)
Dayanarak kural optimizer :
EXISTS
, IN
alt sorgu sonuçları çok büyük olduğunda çok daha hızlıdır .IN
, EXISTS
alt sorgu sonuçları çok küçük olduğunda daha hızlıdır .Dayanarak maliyet optimizer :
Onların ne yaptığını bildiğinizi varsayıyorum ve bu nedenle farklı şekilde kullanıldığını, bu yüzden sorunuzu şu şekilde anlayacağım: Ne zaman EXISTS yerine IN kullanmak için SQL'i yeniden yazmak iyi bir fikir olur, ya da tam tersi.
Bu adil bir varsayım mı?
Düzenleme : Ben soruyorum nedeni birçok durumda bir EXISTS kullanmak yerine IN dayalı bir SQL yeniden yazabilirsiniz ve tersi ve bazı veritabanı motorları için, sorgu eniyileyici iki farklı davranır.
Örneğin:
SELECT *
FROM Customers
WHERE EXISTS (
SELECT *
FROM Orders
WHERE Orders.CustomerID = Customers.ID
)
şu şekilde yeniden yazılabilir:
SELECT *
FROM Customers
WHERE ID IN (
SELECT CustomerID
FROM Orders
)
veya bir birleştirme ile:
SELECT Customers.*
FROM Customers
INNER JOIN Orders ON Customers.ID = Orders.CustomerID
Yani sorum hala duruyor, orijinal poster IN ve EXISTS'in ne yaptığını ve dolayısıyla nasıl kullanılacağını merak ediyor mu, yoksa EXISTS'i kullanmak için IN'yi kullanarak bir SQL'in yeniden yazılmasının mı yoksa tam tersinin iyi bir fikir mi olacağını soruyor mu?
JOIN
birDISTINCT
EXISTS
IN
alt sorgu sonuçlarının çok büyük olduğundan çok daha hızlıdır . alt sorgu sonuçlarının çok küçük olduğundan
IN
daha hızlıdır EXISTS
.
CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT)
GO
CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20))
GO
INSERT INTO t1
SELECT 1, 'title 1', 5 UNION ALL
SELECT 2, 'title 2', 5 UNION ALL
SELECT 3, 'title 3', 5 UNION ALL
SELECT 4, 'title 4', 5 UNION ALL
SELECT null, 'title 5', 5 UNION ALL
SELECT null, 'title 6', 5
INSERT INTO t2
SELECT 1, 1, 'data 1' UNION ALL
SELECT 2, 1, 'data 2' UNION ALL
SELECT 3, 2, 'data 3' UNION ALL
SELECT 4, 3, 'data 4' UNION ALL
SELECT 5, 3, 'data 5' UNION ALL
SELECT 6, 3, 'data 6' UNION ALL
SELECT 7, 4, 'data 7' UNION ALL
SELECT 8, null, 'data 8' UNION ALL
SELECT 9, 6, 'data 9' UNION ALL
SELECT 10, 6, 'data 10' UNION ALL
SELECT 11, 8, 'data 11'
Sorgu 1
SELECT
FROM t1
WHERE not EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id)
Sorgu 2
SELECT t1.*
FROM t1
WHERE t1.id not in (SELECT t2.t1id FROM t2 )
Varsa t1
sizin id boş değere sahiptir ardından Sorgu 1 bunları bulacaksınız, ancak Sorgu 2 boş parametrelerini bulamıyorum.
Yani IN
hiçbir şeyi null ile karşılaştıramazsınız, bu yüzden null için hiçbir sonucu yoktur, ancak EXISTS
her şeyi null ile karşılaştırabilir.
IN
İşleci kullanıyorsanız, SQL motoru iç sorgudan getirilen tüm kayıtları tarar. Öte yandan, kullanırsak EXISTS
, SQL motoru bir eşleşme bulur bulmaz tarama işlemini durduracaktır.
IN sadece eşitlik ilişkilerini (veya öncesinde NOT ile eşitsizliği ) destekler. =
Any / = some ile eşanlamlıdır , örn.
select *
from t1
where x in (select x from t2)
;
EXISTS , IN kullanılarak ifade edilemeyen değişken ilişki türlerini destekler , örn.
select *
from t1
where exists (select null
from t2
where t2.x=t1.x
and t2.y>t1.y
and t2.z like '℅' || t1.z || '℅'
)
;
İddiaya göre EXISTS ve IN arasındaki performans ve teknik farklılıklar , belirli satıcının uygulamalarından / sınırlamalarından / hatalarından kaynaklanabilir, ancak çoğu zaman, veritabanlarının iç kısımlarının anlaşılmaması nedeniyle oluşturulan mitlerden başka bir şey değildir.
Tabloların tanımı, istatistikleri 'doğruluğu, veritabanı yapılandırması ve optimize edicinin sürümü, yürütme planı ve dolayısıyla performans metrikleri üzerinde etkilidir.
Exists
Anahtar kelime doğru veya yanlış değerlendirir, ancak IN
karşılık gelen alt sorgu sütunundaki tüm değer karşılaştırmak anahtar sözcük. Bir diğeri Select 1
ile kullanmak olabilir Exists
komuta. Misal:
SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)
Ancak IN
daha az verimli ve Exists
daha hızlıdır.
Bence,
EXISTS
sorgusunun sonuçlarını başka bir alt sorgu ile eşleştirmeniz gerektiğidir. SubQuery sonuçlarının eşleştiği 1 numaralı sorgu sonuçlarının alınması gerekir. Bir Katıl Tür .. Örn. 2 numaralı sipariş tablosunu da veren müşteriler tablosu 1'i seçin
IN, belirli bir sütunun değerinin IN
bir liste (1,2,3,4,5) içerdiğini almaktır. Eg Aşağıdaki kod kodlarında yer alan müşterileri seçin, yani zip_code değerleri (....) listesinde yer alır.
Ne zaman diğerinin üzerinde kullanılır ... uygun şekilde okunduğunu hissettiğinizde (Niyet daha iyi iletişim kurar).
Fark burada yatıyor:
select *
from abcTable
where exists (select null)
Yukarıdaki sorgu tüm kayıtları döndürür, bir diğeri boş döner.
select *
from abcTable
where abcTable_ID in (select null)
Bir deneyin ve çıktıyı gözlemleyin.
Bir alt sorgu bir NULL
değer döndürdüğünde bildiklerime göre tüm ifade olur NULL
. Bu durumlarda EXITS
anahtar kelimeyi kullanıyoruz . Alt sorgulardaki belirli değerleri karşılaştırmak istiyorsak, IN
anahtar kelimeyi kullanıyoruz .
Hangisinin daha hızlı olduğu, iç sorgu tarafından getirilen sorgu sayısına bağlıdır:
EXIST, doğru veya yanlış olarak değerlendirir ancak IN çoklu değeri karşılaştırır. Kaydın var olup olmadığını bilmiyorsanız, EXIST'i seçmelisiniz
Bunun nedeni, EXISTS operatörünün “en az bulunan” prensibine göre çalışmasıdır. True değerini döndürür ve en az bir eşleşen satır bulunduğunda tabloyu taramayı durdurur.
Diğer taraftan, IN işleci bir alt sorgu ile birleştirildiğinde, MySQL önce alt sorguyu işlemeli ve sonra tüm sorguyu işlemek için alt sorgunun sonucunu kullanmalıdır.
Genel kural, alt sorgu büyük miktarda veri içeriyorsa, EXISTS operatörünün daha iyi bir performans sağlamasıdır.
Ancak, alt sorgudan döndürülen sonuç kümesi çok küçükse, IN işleci kullanan sorgu daha hızlı çalışır.
Anladığım kadarıyla, NULL değerlerle uğraşmadığımız sürece her ikisi de aynı olmalıdır.
Sorgunun = NULL vs değerini döndürmemesi de NULL'dur. http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/
Boolean vs karşılaştırıcı argümanı gelince, bir boolean üretmek için her iki değerin karşılaştırılması gerekir ve eğer durum böyle çalışırsa.
In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.
https://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm#i28403
Bir alt sorgu birden fazla değer döndürürse, dış sorguyu yürütmeniz gerekebilir - koşulda belirtilen sütundaki değerler alt sorgunun sonuç kümesindeki herhangi bir değerle eşleşiyorsa. Bu görevi gerçekleştirmek için in
anahtar kelimeyi kullanmanız gerekir .
Bir kayıt kümesinin olup olmadığını kontrol etmek için bir alt sorgu kullanabilirsiniz. Bunun için, exists
maddeyi bir alt sorgu ile kullanmanız gerekir . exists
Anahtar kelime daima doğru veya yanlış değerini döndürür.
Bunun basit bir cevabı olduğuna inanıyorum. Neden bu işlevi sistemlerinde geliştiren insanlardan kontrol etmiyorsunuz?
Bir MS SQL geliştiricisiyseniz, doğrudan Microsoft'tan gelen yanıt.
IN
:
Belirtilen bir değerin alt sorgudaki veya listedeki herhangi bir değerle eşleşip eşleşmediğini belirler.
Satırların varlığını sınamak için bir alt sorgu belirtir.
EXISTS anahtar kelimesini kullanmanın genellikle çok yavaş olduğunu gördüm (Microsoft Access'te çok doğrudur). Bunun yerine birleştirme işlecini şu şekilde kullanırım: -kullanmalı-anahtar kelimeyi-var-sq-
EXISTS Performansta IN'den Daha Hızlıdır. Filtre ölçütlerinin çoğu alt sorgudaysa IN kullanmak daha iyidir ve Filtre ölçütlerinin çoğu ana sorgudaysa EXISTS kullanmak daha iyidir.
IN işleci kullanıyorsanız, SQL motoru iç sorgudan getirilen tüm kayıtları tarar. Öte yandan EXISTS kullanıyorsak, SQL motoru bir eşleşme bulur bulmaz tarama işlemini durduracaktır.
IN
ve EXISTS
eşdeğer olabilir ve birbirlerine dönüştürülebilir.
JOIN
yerine a olarak kullanabileceğiniz bölümIN
.