Laden...

Query mit langer WHERE-Clause wie verkürzen

Erstellt von dewebey vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.308 Views
D
dewebey Themenstarter:in
119 Beiträge seit 2007
vor 13 Jahren
Query mit langer WHERE-Clause wie verkürzen

verwendetes Datenbanksystem: SQL Server 2008

Hallo,

ich habe ein Problem mit einem langen Query, der irgendwann in einen Timeout rast.
Er ist folgendermaßen aufgebaut:
SELECT * FROM Orders WHERE ID = 1 OR ID = 2 OR ID = 3,....
Die WHERE Clause hat hierbei bis zu 1000 Werte, die angehängt werden.

Gibt es eine Möglichkeit, das schneller zu machen?
Den String auf maximal z.B. 100 Werte zu verkürzen, würde ich gerne vermeiden.

Danke und viele Grüße
Dennis

3.511 Beiträge seit 2005
vor 13 Jahren

Hallo,

ist es immer "OR X = 1 OR X = 2 OR X = n"? Wenn ja, dann besser "WHERE X IN (1, 2, n)".

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

D
211 Beiträge seit 2006
vor 13 Jahren

Und wenn es dann noch inperformant wird, sind wir mit EXISTS sehr gut gefahren

Gruß

DevHB

W
955 Beiträge seit 2010
vor 13 Jahren

Wo kommen die ID's denn her? Werden die "zufällig zusammengewürfelt" oder stehen die im Zusammenhang mit anderen Daten in der DB?

54 Beiträge seit 2010
vor 13 Jahren

Alternativ, falls das mit den IDs oben mehr als nur Symbolcharakter hat

SELECT * FROM Orders WHERE (ID ≥ 1 AND ID ≤ 123) OR (ID ≥ 150 AND ID ≤ 1000) OR ...

Die Abfragen quasi in zusammenhängende bereiche zusammenfassen, wenn das möglich ist.

M
118 Beiträge seit 2008
vor 13 Jahren

SELECT * würde ich auch gleich vermeiden. Besser die gewünschten Spalten benennen. (wobei das natürlich nur einen minimalen performance-gewinn gibt)

D
615 Beiträge seit 2009
vor 13 Jahren

Naja ich glaube wir brauchen schon ein paar Infos mehr....

Fals möglich wäre auch sowas zudenken :

Rollen erstellen, Jede Order hat eine RolleID. Nun die Datensätze per Rolle abrufen (where rolle ....) -> (gruppierung)

Beste Grüsse

Diräkt

H
208 Beiträge seit 2008
vor 13 Jahren

Manchmal hilft auch folgendes:

Temporäre Tabelle erstellen, nur mit einer Spalte für die ID-Werte:

create table #tmp
(
    ID int
)

Alle IDs nach denen gesucht werden soll dort einfügen:

insert into #tmp values (1)
insert into #tmp values (2)
usw.

Und dann bei der eigentlichen Abfrage die Temptabelle auf die richtige joinen:

select tbOrders.Spalte1, tbOrders.Spalte2, ...
from tbOrders
inner join #tmp on tbOrders.ID = #tmp.ID

So werden nur die Datensätze mit den IDs gefunden die in der Temptabelle stehen.
Ob's was für die Performance bringt kann man so pauschal nicht sagen...ist aber einen Versuch wert.

3.511 Beiträge seit 2005
vor 13 Jahren

Der wohl performanteste Weg ist es einen Tabellen-Datentyp zu definieren und diesen als Parameter für eine Stored Procedure nehmen.


CREATE TYPE dbo.IdTableType AS TABLE (ID int)

CREATE PROCEDURE dbo.GetValues (@idTable dbo.IdTableType READONLY)
AS
BEGIN
  SELECT * FROM Tabelle
  INNER JOIN @idTable ON Tabelle.ID = @idTable.ID
END

In c# muss für den Parameter dann eine DataTable als Objekt übergeben werden und fertig. Schneller wird man es nicht hinbekommen.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

D
dewebey Themenstarter:in
119 Beiträge seit 2007
vor 13 Jahren

vielen Dank für die Vorschläge.
Ich bekomme die Datensätze aus einem Affiliates Programm, also von extern.
Deswegen sind die auch nicht fortlaufend.