Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Query mit langer WHERE-Clause wie verkürzen
dewebey
myCSharp.de - Member



Dabei seit:
Beiträge: 119
Herkunft: Rust / Baden-Baden

Themenstarter:

Query mit langer WHERE-Clause wie verkürzen

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Khalid
myCSharp.de - Experte

Avatar #avatar-2534.gif


Dabei seit:
Beiträge: 3.511
Herkunft: Hannover

beantworten | zitieren | melden

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)
private Nachricht | Beiträge des Benutzers
DevHB
myCSharp.de - Member



Dabei seit:
Beiträge: 211
Herkunft: Deutschland, Bremen

beantworten | zitieren | melden

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

DevHB
private Nachricht | Beiträge des Benutzers
witte
myCSharp.de - Member



Dabei seit:
Beiträge: 955

beantworten | zitieren | melden

Wo kommen die ID's denn her? Werden die "zufällig zusammengewürfelt" oder stehen die im Zusammenhang mit anderen Daten in der DB?
private Nachricht | Beiträge des Benutzers
Xander
myCSharp.de - Member

Avatar #avatar-3215.jpg


Dabei seit:
Beiträge: 54
Herkunft: Sonneberg

beantworten | zitieren | melden

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.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Xander am .
private Nachricht | Beiträge des Benutzers
Mackerlama
myCSharp.de - Member



Dabei seit:
Beiträge: 118
Herkunft: Thüringen

beantworten | zitieren | melden

SELECT * würde ich auch gleich vermeiden. Besser die gewünschten Spalten benennen. (wobei das natürlich nur einen minimalen performance-gewinn gibt)
private Nachricht | Beiträge des Benutzers
Diräkt
myCSharp.de - Member



Dabei seit:
Beiträge: 611
Herkunft: Schweiz

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
haarrrgh
myCSharp.de - Member



Dabei seit:
Beiträge: 208
Herkunft: Raum Köln

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Khalid
myCSharp.de - Experte

Avatar #avatar-2534.gif


Dabei seit:
Beiträge: 3.511
Herkunft: Hannover

beantworten | zitieren | melden

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)
private Nachricht | Beiträge des Benutzers
dewebey
myCSharp.de - Member



Dabei seit:
Beiträge: 119
Herkunft: Rust / Baden-Baden

Themenstarter:

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers