2016-07-23 20 views
0

ich so etwas wie dieses:LEFT JOIN oder Wählen Sie in wählen (SQL - Geschwindigkeit der Abfrage)

SELECT CompanyId 
FROM Company 
WHERE CompanyId not in 
    (SELECT CompanyId 
    FROM Company 
    WHERE (IsPublic = 0) and CompanyId NOT IN 
     (SELECT ShoppingLike.WhichId 
      FROM Company 
      INNER JOIN 
      ShoppingLike ON Company.CompanyId = ShoppingLike.UserId 
      WHERE (ShoppingLike.IsWaiting = 0) AND 
       (ShoppingLike.ShoppingScoreTypeId = 2) AND 
       (ShoppingLike.UserId = 75) 
     ) 
    ) 

Es verfügt über 3 wählen, ich möchte wissen, wie könnte ich es haben, ohne 3 wählt zu machen, und die hat man bessere Geschwindigkeit für 1 Million Rekord? "Auswählen in Auswahl" oder "Links verbinden"?

+0

Wenn Leistung ein Problem ist, versuchen Sie jede Version Ihrer Daten in Ihrer Datenbank auf Ihrer Hardware und sehen Sie, welche schneller ist. –

+0

Es hat zwei Fragen, ich kann nicht links Join vorbereiten, und für große Daten kann ich es nicht testen, weil ich nicht habe :( – dan

+0

wenn MS SQL es für Sie tun, dann mach dir keine Sorgen, weil sein Optimierer optimieren wird Ihre Abfrage. Sie können Index auf CompanyId machen, um MS SQL zu helfen, Abfrage viel schneller zu tun. – Mahmoud

Antwort

0

Meine Erfahrungen stammen von Oracle. Es gibt nie eine richtige Antwort auf die Optimierung von kniffligen Abfragen, es ist eine Zusammenarbeit zwischen Ihnen und dem Optimierer. Sie müssen überprüfen, erklären Pläne und manchmal Spuren, oft in jeder Phase des Schreibens der Abfrage, um herauszufinden, was der Optimierer im Denken. Having said that:

  • Sie konnten die äußere SELECT, indem Sie den gesamten Inhalt es ist subquery WHERE-Klausel in einer NOT( ... ) entfernen. Auf den ersten Blick wird dieser äußere vollständige Scan des Unternehmens (oder dessen Index von CompanyId) verhindert. Probieren Sie es aus, überprüfen Sie, ob die Ausgabe gleich ist und erhalten Sie Timings, und entfernen Sie sie dann vorübergehend, bevor Sie das Folgende versuchen. Die NOT() kann durchaus dazu führen, dass der Optimierer aufhört, einen ANTI-JOIN gegen die ShoppingLike-Unterabfrage zu berücksichtigen, weil ein implizites OR erstellt wurde.
  • Stellen Sie sicher, dass CompanyId und WhichId als NOT NULL Spalten definiert sind. Ohne dies (oder ähnliches wie eine explizite CompanyId IS NOT NULL) werden ANTI-JOIN-Optionen oft verworfen.
  • Die innerste Unterabfrage ist nicht korreliert (verweist nicht auf die äußere Abfrage) und kann daher separat extrahiert und abgestimmt werden. Als eine Art des Stils würde ich die Tabellennamen um die INNER JOIN tauschen, wie ShoppingLike zuerst gescannt werden soll, da es alle Filter dagegen hat. Es macht keinen Unterschied, aber es liest sich einfacher und ermöglicht es, einen Hinweis zu verwenden, um Tabellen in der angegebenen Reihenfolge zu scannen. Ich würde sogar die Notwendigkeit der Unternehmenstabelle in dieser Unterabfrage in Frage stellen.
  • Sie haben NOT IN verwendet, wenn manchmal der sehr ähnliche NOT EXISTS dem Optimierer mehr/alternative Optionen gibt.

Alles oben genannte ist nur Versuch und Irrtum, es sei denn Sie beginnen, den Erklärungs-Plan zu versuchen. Oracle kann bei einem folgenden Wind zwischen LEFT JOIN und INSELECT konvertieren. 1M + Reihen schaffen Zeit, um zu investieren.

+0

So danke :) es ist mir helfen mehr als, was ich brauche – dan