AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi WHERE über alle Felder

WHERE über alle Felder

Ein Thema von Angel4585 · begonnen am 20. Apr 2006 · letzter Beitrag vom 21. Apr 2006
Antwort Antwort
Seite 2 von 2     12
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#11

Re: WHERE über alle Felder

  Alt 20. Apr 2006, 23:27
Ich würde mal sagen, das das ein gutes Beispiel für ein falsches Tabellendesign (in Bezug auf die Abfrageanforderung) ist.
Damit ein DB-Server nicht unnötig ausgebremst wird, sollten die durchzusuchenden Felder indiziert sein. Falls ein 'LIKE' Operator verwendet werden muss, sollte kein Escape-Zeichen *vor* dem Suchstring auftreten, um die Suche mit Hilfe eines Indexes zu ermöglichen.
Dazu kann man mehrere Indexe erstellen, eines für jedes durchzusuchende Feld, oder man befolgt die die Grundregeln des DB-Designs, und erstellt eine separate Tabelle 'SearchFields' mit drei Feldern: Einem Link zum Masterdatensatz in der ursprünglichen Tabelle, Einem mit dem Inhalt, sowie eventuell noch Einem, das die Unterscheidung ermöglicht, ob es sich um das ursprüngliche 'Feld1', 'Feld2'... handelt.

Dann reduziert sich die Abfrage auf
SQL-Code:
select *
  from Tabelle1 alias T1 join
       SearchFields alias SF
         on SF.IDMaster = T1.ID
 where SF.Value = 'FooBar%'
Das ist bei einem Index auf SearchFields.Value optimal schnell.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von Mackhack
Mackhack

Registriert seit: 29. Nov 2003
Ort: San Diego, CA/USA
1.446 Beiträge
 
Delphi 2006 Architect
 
#12

Re: WHERE über alle Felder

  Alt 20. Apr 2006, 23:30
Hi,

Zitat von alzaimar:
...oder man befolgt die die Grundregeln des DB-Designs, und erstellt eine separate Tabelle 'SearchFields' mit drei Feldern: Einem Link zum Masterdatensatz in der ursprünglichen Tabelle, Einem mit dem Inhalt, sowie eventuell noch Einem, das die Unterscheidung ermöglicht, ob es sich um das ursprüngliche 'Feld1', 'Feld2'... handelt.
kannst du das mit der seperaten Tabelle bissi genauer erklaeren, das hoert sich interessant an. Kannst mir aber auch ne PM schreiben wenn du magst.

Dank dir auf jedenfall schonmal!
Um etwas Neues zu schaffen muss man seine Ohren vor den Nein-sagern verschliessen um seinen Geist öffnen zu können.
(George Lukas)
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.902 Beiträge
 
Delphi 2010 Professional
 
#13

Re: WHERE über alle Felder

  Alt 21. Apr 2006, 00:03
Zitat von Mackhack:
kannst du das mit der seperaten Tabelle bissi genauer erklaeren, das hoert sich interessant an.
Hat er doch schon...
naja hier etwas bildlicher:
  • Haupttabelle:
    int ID
    Feld1
    Feld2
    FeldBlaBla
  • SuchFeldTabelle
    int ID
    string Name
  • SuchTabelle
    int LinkAufHauptTabelle
    int LinkAufSuchFeldTabelle
    string WertInDemGesuchtWerdenKann
SQL-Code:
SELECT Feld1
      ,Feld2
      ,FeldBlaBla
FROM HauptTablle
WHERE ID in (SELECT LinkAufHauptTabelle
             FROM SuchTabelle
             WHERE WertInDemGesuchtWerdenKann like :SuchAusdruck)
Die zweite Tabelle könnte man hernehmen um den Suchwerten noch bestimmte Gruppen oder anderen Werte zu geben, die man beim Suchen als Einschränkung hernehmen könnte. Sozusagen ein Minihauch Metadaten in dem abstraken Beispiel.
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#14

Re: WHERE über alle Felder

  Alt 21. Apr 2006, 00:30
Zitat von MrSpock:
wenn Feld1 den Eintrag "Mr" und Feld2 den Eintrag "Spock" hat liefert die Konkatenierungslösung bei der Suche nach "MrSpock" auch einen Treffer
Völlig korrekt, MrSpock. Aber auch nur dann, wenn nicht irgendwo auch noch ein Leerzeichen falsch steht. Feld1 müßte außerdem mit Mr enden und Feld2 direkt wieder mit Spock beginnen. Mein "Spezialfall"-Bsp. bezog sich auf so was :

ist es so hinterlegt :

Delphi-Quellcode:
Herr XY
z.Hd. Frau XY
oder so :

Delphi-Quellcode:
Herr
XY z.Hd. Tipse
Der Sucher wirds nicht mehr wissen. Er weiß nur, daß irgendwas mit XY vorhanden sein muß. In der Anrede oder eben im Namen. Also muß ich sowieso alle relevanten Adressfelder durchsuchen. Konkateniere ich nun das Ergebnis, dann sind die Originalfelder egal. Die Adresse wird auf jeden Fall gefunden !

Die Theoretiker werden wohl auch bemängeln, daß LIKE, %, dazu noch vorne und hinten im Suchbegriff usw. langsamer ist als die Felder mit OR zu überprüfen. Das Wort Index ist ja bereits gefallen. Wenn ein Enduser allerdings den XY-Typ innerhalb von 10 Sek. findet, dann ist ihm das wohl viel lieber, als sich 1 Min. einen richtigen Suchbegriff auszudenken und dann 8,8 Sekunden zu warten, um gesagt zu bekommen, daß nichts gefunden wurde, weil das falsche Feld durchsucht wurde.
Gruß
Hansa
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#15

Re: WHERE über alle Felder

  Alt 21. Apr 2006, 08:13
@Hansa: Es geht hier nicht um Zeitunterschiede von 1,2 Sekunden, wie Du so schön (aber falsch) süffisant angemerkt hast, sondern um drastische Geschwindigkeitsgewinne: Während die Suche über mit Hilfe eines Indexes, unabhängig von der Tabellengröße, in etwa konstant bleibt, wächst der Suchaufwand ohne Index linear: Doppelte Tabellengröße = Doppelte Suchzeit. Wenn man nur mit Tabellen von einigen Tausend Einträgen arbeitet, ist es wirklich egal, aber bei einigen Hunderttausend Einträgen macht sich das schon bemerkbar. Dann beträgt der Zeitunterschied etwa das 100 bis 1000-fache. Eine einfache Suche per Index ist in einigen 100 ms durchgeführt, während die sequentielle Suche ohne Index durchaus Minuten, wenn nicht sogar Stunden dauern kann.

Im Übrigen sind meinen Kunden Suchzeiten von 10 Sekunden nicht egal. Ein solches Schneckentempo erreiche ich höchstens bei Summierungen, ansonsten verlange ich von meiner DB, das die Suchergebnisse *sofort* erscheinen. Ein DB-Server sollte nicht suchen, sondern finden.

10 Sekunden...

Ich würde zwei Tabellen nehmen:
Aus einer Tabelle
T1:
int ID
string Name
string Feld1
string Feld2
string Feld3

werden zwei Tabellen
T2:
int ID
string Name

und
SearchFields:
int IDT2
int sfCode
string FieldValue

Ein Datensatz in T1 (1,'MyName','MyField1','MyField2','MyField3') wird auf ein Feld in T2 sowie drei Felder in SearchFields aufgeteilt:
T21,'MyName')
SearchFields:
(1,1,'MyField1')
(1,2,'MyField2')
(1,3,'MyField3')

Und eine Suche in einem der Felder reduziert sich dann auf das bereits beschriebene:
SQL-Code:
select *
  from T2 join
       SearchFields alias SF
          on SF.IDT2 = T2.ID
 where SF.FieldValue ='MySearch'
Mit einem Index auf den SearchFields.FieldValues hast Du eine Recherchemöglichkeit, die ohne Verzögerung das Ergebnis liefert.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
WoGe

Registriert seit: 16. Jun 2005
Ort: Kelkheim
178 Beiträge
 
Delphi 10.3 Rio
 
#16

Re: WHERE über alle Felder

  Alt 21. Apr 2006, 11:42
Hallo,

man muss das Problem übrigens nicht in mehrere Tabellen zerlegen, folgendes geht, zumindest mit FB1.5 auch:

SQL-Code:
create view SuchAnschrift (
    KUNDENNO,
    ANSCHRIFT
    )
AS
select adr.KUNDENNO, adr.ANSCHRIFT1
from woreadr adr
where adr.ANSCHRIFT1 is not null
union
select adr.KUNDENNO, adr.ANSCHRIFT2
from woreadr adr
where adr.ANSCHRIFT2 is not null
union
select adr.KUNDENNO, adr.ANSCHRIFT3
from woreadr adr
where adr.ANSCHRIFT3 is not null
;
Über Performance kann ich leider nichts sagen, da ich hier nicht soviele Daten habe.

mfg
wo
  Mit Zitat antworten Zitat
Angel4585

Registriert seit: 4. Okt 2005
Ort: i.d.N.v. Freiburg im Breisgau
2.199 Beiträge
 
Delphi 2010 Professional
 
#17

Re: WHERE über alle Felder

  Alt 21. Apr 2006, 14:37

OK..
also nachdem ihr jetzt teilweise eine Nacht darüber geschlafen habt
und einige vielleicht sogar Albträume hatten..

Welche Version ist denn jetzt am Effektivsten um
in ALLEN Feldern einer Tabelle
nach einem Teilstring zu suchen?

Martin Weber
Ich bin ein Rüsselmops
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#18

Re: WHERE über alle Felder

  Alt 21. Apr 2006, 14:45
Wenn Du in ALLEN Felder einer Tabelle nach etwas suchen willst, dann ist die Tabelle falsch designed. Punkt. Denn wenn ich in mehreren Feldern etwas suchen will, enthalten diese semantisch äquivalente Inhalte, ergo gehören diese Felder in eine separate Tabelle.
Erzeuge eine Detailtabelle, wie vorher beschrieben. Alles Andere ist Rumgefrickele.

Wenn du allerdings nur ein paar hundert Datensätze hast, lohnt es den Aufwand nicht. Suche dann in allen Feldern durch OR verknüpft. Ob die indiziert sind, oder nicht, ist dann auch egal. Vermutlich wird das DBMS die Indexe gar nicht verwenden.

Bei vielen Records musst Du es richtig machen (Detailtabelle), sonst wird der DB-Server unnötig ausgebremst.

Dessenungeachtet ist es *immer* am Besten, man probiert es aus.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:17 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf