2010-11-20 4 views
1

ich dieses Beispiel auf den MySQL Tutorial gefunden:Performance vs SELECT JOIN ... WHERE mit einem Beispiel

SELECT article, dealer, price 
FROM shop 
WHERE price=(SELECT MAX(price) FROM shop); 

Meine Frage: ist die Unterabfrage (SELECT MAX (Preis) FROM shop) eine Zeit einmal getan oder es wird wiederholt ausgeführt, bis der maximale Preis für die Abfrage gefunden wird?

In Bezug auf die Leistung ist diese andere Lösung besser?

SELECT s1.article, s1.dealer, s1.price 
FROM shop s1 
LEFT JOIN shop s2 ON s1.price < s2.price 
WHERE s2.article IS NULL; 

Danke.

Antwort

2

Die Unterabfrage ist nicht korreliert, so dass jede sinnvolle Implementierung sie nur einmal auswertet. Beachten Sie, dass MySQL ein Problem mit IN hat allerdings, wo die semantisch äquivalent

SELECT article, dealer, price 
FROM shop 
WHERE price IN (SELECT MAX(price) FROM shop); 

Abfrage führt zu dem Untermehrfach ausgewertet.

Für die Bewertung der Leistung müssen Sie die explain plan für beide in Ihrem bestimmten RDBMS betrachten.

Die effizienteste Lösung könnte SELECT TOP .. WITH TIES oder gleichwertig sein, wenn Sie einen Deckungsindex für die Spalte price haben und Ihr RDBMS über ein solches Konstrukt verfügt.

+0

Warum hat MySQL dieses Problem mit IN? Wo finde ich Unterlagen dazu? – BMario

+0

@BMario - Siehe http://stackoverflow.com/questions/3417074/why-would-an-in-condition-be-slower-than-in-sql –

-1

Ich kann beide schlagen:

SELECT article, dealer, price 
FROM shop 
WHERE price=MAX(price) 

Edit: Whoops, nicht auf meinem Test-Server arbeiten:/

+0

Wird nicht funktionieren. In einer Where-Klausel können keine Aggregate verwendet werden. –

+1

@J V haha ​​wie würde mysql max von welchen Werten kennen, bevor sogar die Werte gefunden werden. Mochte das Vertrauen und die Reaktion auf das Scheitern obwohl –

+0

bekomme ich Punkte für einen guten Sport: D –

-1

einen Join verwenden sollte besser sein als eine verschachtelte Unterabfrage.

+0

Belege für diese Behauptung? Im OP-Fall sieht die Unterabfrage massiv besser aus. Da zwei Indexsuchvorgänge einen Index-Scan und einen Dreiecks-Join problemlos übertreffen würden. Natürlich kann der Optimierer die Abfragen trotzdem transformieren. –

+1

-1. Dies ist eine völlig falsche Aussage. Ich weiß nicht einmal, wo ich anfangen soll. –

1

Sie haben Tags für MySql, T-Sql und PL/Sql, ich vermute, die Antwort ist für jeden unterschiedlich.

Die Antwort könnte auch davon abhängen, welche Indizes Sie haben und wie einzigartig die Werte im Feld [price] sind.

Führen Sie den Abfrageanalysator aus, um zu sehen, was der tatsächliche Abfrageplan ist.

0

Ich habe SQL Server 2008 zu diesen drei Variationen der Aquarius verwendet. Bei meinen Tests wird die AdventureWorks-Datenbank mithilfe von ProductInventory im Produktionsschema abgefragt. Die drei Abfragen sind:

declare @max int 
Select @max = MAX(Quantity) FROM [AdventureWorks].[Production].[ProductInventory] 
SELECT TOP 1000 [ProductID] 
     ,[LocationID] 
     ,[Shelf] 
     ,[Bin] 
     ,[Quantity] 
     ,[rowguid] 
     ,[ModifiedDate] 
    FROM [AdventureWorks].[Production].[ProductInventory] 
    WHERE Quantity = @max 

SELECT TOP 1000 [ProductID] 
     ,[LocationID] 
     ,[Shelf] 
     ,[Bin] 
     ,[Quantity] 
     ,[rowguid] 
     ,[ModifiedDate] 
    FROM [AdventureWorks].[Production].[ProductInventory] 
    WHERE Quantity = (Select MAX(Quantity) FROM [AdventureWorks].[Production].[ProductInventory]) 


SELECT TOP 1000 AW1.[ProductID] 
     ,AW1.[LocationID] 
     ,AW1.[Shelf] 
     ,AW1.[Bin] 
     ,AW1.[Quantity] 
     ,AW1.[rowguid] 
     ,AW1.[ModifiedDate] 
    FROM [AdventureWorks].[Production].[ProductInventory] AW1 
LEFT JOIN [AdventureWorks].[Production].[ProductInventory] AW2 ON AW1.Quantity < AW2.Quantity 
WHERE AW2.ProductID IS NULL; 

die „Show geschätzten Abfrageplan“ Symbol verwenden ich die exection Ereignisse für drei Fälle vergleichen. Die Ergebnisse sind:

  1. Deklarieren einer Variablen und Füllen der Variablen ist 5% schneller als eine Unterauswahl in der Where-Klausel.
  2. Die Verbindung ist 98% langsamer als die subselect
  3. Die Verbindung ist 99% langsamer als die Variable

Mein Vorschlag ist, eine Variable zu deklarieren und sie füllen.Verwenden Sie die Variable in der WHERE-Klausel

+0

Es sollte keinen besonderen Vorteil der Verwendung einer Variablen geben. Vielleicht liegen die beiden 0% Chargen tatsächlich zwischen 0,25% und 0,49%, was bedeutet, dass wenn beide Schritte addiert werden, ein Anzeigewert auf 1% gerundet wird. In der Tat, wenn Sie sich die Pläne ansehen, werden Sie sehen, dass beide genau die gleiche Arbeit machen. –

+0

Obwohl gesagt wurde, dass die Zuweisung zu einer Variablen in den folgenden Situationen nützlich sein kann. (1) Um mit OPTION (RECOMPILE) zu verwenden, um bessere Kardinalitätsschätzungen für den Rest der Abfrage zu erhalten. (2) In parallelen Ausführungsplänen können bessere Pläne möglich sein. (Quelle: "Microsoft SQL Server 2005 Query Optimierung und Tuning") –

1

, um Ihre Frage zu beantworten, die skalare Unterabfrage (SELECT MAX (Preis) FROM-Shop) wird einmal ausgeführt und dann an die Hauptabfrage als Wert in MySQL übergeben.

So ist diese Abfrage so schnell wie alles andere, was Sie sich vorstellen können.

-2

Sie sollten sich nicht kümmern. Jeder anständig moderne Datenbankserver wird verstehen, was Sie wollen und die Abfrage so effizient wie möglich durchführen. SQL ist deklarativ, nicht zwingend (dh Sie sagen, was Sie wollen, Sie sagen nicht, wie es abgerufen werden soll).

+0

In der Theorie ja. In der Praxis verbringt der Optimierer nur eine gewisse Zeit damit, Transformationsregeln anzuwenden, und die Art, wie eine Abfrage geschrieben wird, kann das "Wie" stark beeinflussen. Sie brauchen nicht weiter als [RC_Clelands Antwort] (http://stackoverflow.com/questions/4232570/performance-of-join-vs-select-where-with-an-example/4232785#4232785) nach dem Beweis dafür zu suchen. –

+3

Dem muss ich hier widersprechen. SQL ist nicht nur eine Black Box, die magisch funktioniert. Es ist wichtig zu verstehen, wie Ihre Abfragen bewertet werden, bevor Sie sie ausführen - und wenn Sie das nicht wissen, führt dies oft zu allen Arten von Leistungsproblemen - einige davon werden nicht einfach zu optimieren sein. –

+0

Wenn dies der Fall wäre, gäbe es keine Tools wie 'explain plan'. Die Wahrheit der Sache ist anders gebildet SQL wird verschiedene Ausführungspläne geben, so ist es wichtig zu wissen, wie man noch tunen. – Donnie