Re: Mehr Speed?
Andreas Gabriel <[email protected]>
| Newsgroups | gmane.comp.web.zope.german |
|---|---|
| Organization | Hochschulrechenzentrum Philipps-Universitaet Marburg |
| Message-ID | <[email protected]> |
Hallo Dieter,
Dieter Maurer schrieb:
> Nein. "makeAdvancedQuery" übersetzt nur von der eingeschränkten
> Katalog-Anfragespezifikation in die reichere "AdvancedQuery" Spezifikation.
> Es enthält keine allzu große Intelligenz.
Schade, aber dann hat es sich wenigstens gelohnt in unimr.compositeindex
Energie zu investieren. Dort wird die Suche (wie bei RDBMs) unter
bestimmten Voraussetzungen automatisch auf den Multi-Column Index
umgestellt.
> Wenn man in einem "AdvanceQuery"/"ManagableIndex" etwas ähnliches
> Unterstützen wollte, dann würde ein spezieller Indextyp der
> natürliche Ansatz.
Klar!
> Was ist denn Dein Use-Case für einen solchen Multi-Column Index?
Use-Case 1!
> Use-Case 1:
> ===========
> Du möchtest über Paare ("review_state", "portal_type") suchen.
> Das geht alternativ auch flexibler über 2 separate Indexe (die man auch für
> andere Zwecke verwenden kann) und eine "Und" Subquery.
Tja, das ist ja der Haken bei mehr als 100000 Entries im Catalog.
Und-Verknüpfungen werden über >=2 separate Indexe sehr langsam und
es werden unnötigerweise Daten geladen, die später bei der Schnittmenge
weggeworfen werden. Letzteres quält den ZODB-Cache. Und zum Beispiel bei
Plone wird häufig über drei bis vier Field/KeywordIndexe abgefragt,
wobei letztendlich nur 0 bis 100 Treffer herauskommen. Da lohnt es sich
unmittelbar einen Multi-Column Index einzusetzen, da die Schnittmengen
schon vorberechnet sind und somit viel kleinere Sets bei der Suche
geladen werden müssen. Bestenfalls ist man > 2-3 mal schneller bei der
Abfrage.
> Du legst einen "Managable FieldIndex" an, fügst 2 "AttributeLookup"s
> für "review_state" und "portal_type" hinzu und wählst als
> "combine_type" "aggregate".
d.h. implizit erzeugt man einen OOBTree mit einem Tuple als Key, oder?
index[<(column1, column2)>] = [ docId, ...]
Im Prinzip machen es wir genau so bei unserem CompositeIndex, nur dass
wir einen zweiten Index-Level für die einzelnen Tuple-Elemente
einführen, der auf den Tuple-Index zeigt:
toupleXY = <(column1, column2, ...)>
comp_index1[<column1>] = [ toupleXY , ...]
comp_index2[<column1>] = [ toupleAB , ...]
...
index[toupleXY] = [ docId, ...]
index[toupleAB] = [ docId, ...]
...
> Suchen sehen so aus: "Eq(index, (review_state, portal_type))".
> Wenn man den Index missbrauchen möchte für Suchen nach "review_state",
> kann man "Between(index, (review_state, ''), (review_state, 100*'\xff'))"
> verwenden.
Interessant, dass man einen Range bei Tuples so abfragen kann :). Den
zweiten Index Level hatten wir eingeführt, damit wir kompatibel zu den
Operatoren von Field- und KeywordIndex sowie unabhängig von der Anzahl
und Reihenfolge der abgefragten (atomaren) Indexe bleiben.
Des Weiteren ist das Anlegen der Tuple-Keys nicht so trivial, wenn man
auch einen KeywordIndex mittels Multi-Column Index abfangen möchte, z.B.
class TestObject():
self.portal_type = 'TestObject'
self.review_state = 'pending'
self.subject = ['Tagung','Medizin']
Hier soll der Multi-Column Index-Key aus drei Elementen bestehen
(<review_state>,<portals_type>,<subject>)
Für maximale Flexibilität muss beim Indizieren permutiert werden, d.h.
es entstehen zwei Tuple/Index-Einträge für ein Objekt:
('pending','TestObject','Tagung')
('pending','TestObject','Medizin')
Macht das Dein "combine_type" "aggregate"?
Eine Abfrage wie folgt
klassisch:
catalog(review_state = ['pending','visible'], \
portal_type = 'TestObject', \
subject = { 'query': ['Tagung','Medizin'], \
'operator': 'and'})
AdvancedQuery:
query = In(review_state, ['pending','visible']) & \
Eq(portal_type, 'TestObject') & \
Eq(subject, 'Tagung') & \
Eq(subject, 'Medizin')
müsste für den Multi-Column Index (mci) so permutiert bzw. übersetzt werden:
query = And((In(mci, [('pending','TestObject','Tagung'),
('visible','TestObject','Tagung')]),
In(mci, [('pending','TestObject','Medizin'),
('visible','TestObject','Medizin')]))
)
> Nach meinem Verständnis von Multi-Column-Indexen
> sind sie eine Optimierung, wenn Du überwiegend nach Tupeln (Use-Case 1 oben)
> suchst. Mit einem entsprechenden Multi-Column-Index hast Du einen einzigen
> Index-Zugriff -- mit separaten Indexen musst Du die "Und"-Subquery auswerten,
> dazu sind n-Indexzugriffe notwendig.
Ja, das ist klar. Ich wollte nur wissen, ob ManagableIndex bzw.
AdvancedQuery oben genannte Permutationen automatisch beim Bilden der
Index-Einträge berücksichtigt, und einen Query, der zunächst auf atomare
Indexe angesetzt wurde, automatisch wandelt/optimiert. Wie ich jetzt
schlussfolgere, leider nicht. Obwohl es sich bei ManagableIndex,
schon wegen der variablen Optionen im ZMI, geradezu anbieten würde.
Scharmant bei den RDBMs ist ja gerade, dass man sich beim SELECT nicht
darum kümmern muss, ob man einen atomaren oder Multi-Column Index
einsetzt. Dies war auch der Grund dafür, dass wir ein eigenes Produkt
geschrieben haben.
Danke & Gruß
Andreas
--
Dr. Andreas Gabriel, Hochschulrechenzentrum
Hans-Meerwein-Str., 35032 Marburg, fon +49 (0)6421 28-23560 fax -26994
----------------- Philipps-Universitaet Marburg ----------------------
_______________________________________________
zope mailing list
[email protected]
https://mail.dzug.org/mailman/listinfo/zope