Bug #9194
FWD selects the wrong index when using CONTAINS?
50%
History
#1 Updated by Radu Apetrii almost 2 years ago
CONTAINS clause. In terms of reference notes, here are some:
- Index selection notes: #8357-119, #8357-121, #8357-130
- Testing examples: #8357-120, #8357-122, #8357-124, #8357-125.
The current worry is that the order of rules in the Index Selection phase might be wrong. I'll summarize in the following post some examples, and I will also check the order of rules in both 4GL and FWD to get some findings/results.
#3 Updated by Radu Apetrii almost 2 years ago
Here's a summary of what happened so far:
Example 1 Show
After this step, I added to the test table one more index: idx2 which is an unique index on the f2 and f3 fields (both integers). This leads us to example 2.
Example 2 Show
Example 3 Show
Then, we were interested in what is taken into consideration when sorting records from a word-index perspective.
Example 4 Show
The next step is to check the order from the Index Selection Rules in both 4GL and FWD.
#4 Updated by Radu Apetrii almost 2 years ago
Greg Shah wrote (note #8357-130):
Further discoveries:Index Selection Rules shows that
USE-INDEX(rule 1) and "unique index with all components in equality matches" (rule 2) should have preference overCONTAINS(rule 3).
- About Rule 1: In 4GL, a query cannot have both
CONTAINSandUSE-INDEX. If I write such query, I get the errorUSE-INDEX cannot be used with CONTAINS. (3316). This happens when I save the working file (i.e. at compile time). - About Rule 2: If the
WHEREclause has all the components (of a unique index) in equality matchesANDaCONTAINSclause, both indexes are evaluated. TheWHERElooks likeword-index check AND unique index check.- The xref compile report shows both
SEARCH fwd.test idx_word(word-index) andSEARCH fwd.test idx2(unique index). In 4GL, what happens in this case? Are both indexes used or is the last index the chosen one? - Important note: The order of these
SEARCHstatements for theANDcase is always the same, despite rearranging the operands in theWHEREclause. The word-indexSEARCHalways appears before the unique indexSEARCHin the xref report.
- The xref compile report shows both
- About Rule 2 part 2: If I replace the
ANDin theWHEREclause with anOR, so that theWHERElooks likeword-index check OR unique index check, still both indexes are evaluated.- However, the order of
SEARCHin the xref report depends on the order of operands in theWHEREclause.- If the where is
word-index check OR unique index check, xref looks likeSEARCH fwd.test idx_word(word-index) andSEARCH fwd.test idx2(unique index). - If the where is
unique index check OR word-index check, xref looks likeSEARCH fwd.test idx2(unique index) andSEARCH fwd.test idx_word(word-index).
- If the where is
- However, the order of
- Other notes about Rule 2:
- If I go from "all components in equality matches" to "all components except one in equality matches", and that other component having "range matches", then 4GL chooses the word-index, while FWD chooses the unique index.
- About Rule 3: In a query with a
WHEREclause that has aCONTAINSand nothing else (noBYclauses, no nothing), 4GL chooses the word-index, while FWD chooses the primary index.- So even in this simple case FWD is unable to select the right index (the word-index).
All in all, I think the order of rules in the wiki is right. Maybe, and this is just a presumption, FWD is unable to select the word-index at all (i.e. the rules point to other indexes and never to the word-index)?
#5 Updated by Greg Shah almost 2 years ago
Good findings. Please edit the wiki page to include your important clarifications.
#6 Updated by Andy Edwards almost 2 years ago
Hi all, we have completed the "indeterminate sorting" review and are now starting to make the necessary changes, hence I thought I'd check out what the latest is on the CONTAINS topic. I've read the previous ticket and this one and please correct me if I'm wrong, but my conclusion from it is that FWD will not use the same WORD-INDEX rules as the 4GL so we will have to add a BY clause to get the sequence we had previously?
Also, I'm clear that FWD will pick the same records as the 4GL but if it's not going to use the WORD-INDEX then is there going to be a performance issue with queries using CONTAINS in FWD? Just in 4GL terms if you're using the PRIMARY index on a table to do a 'CONTAINS' type function in a query then it will be much slower?
Thanks, Andy.
#7 Updated by Eric Faulhaber almost 2 years ago
- Assignee set to Radu Apetrii
Andy Edwards wrote:
Hi all, we have completed the "indeterminate sorting" review and are now starting to make the necessary changes, hence I thought I'd check out what the latest is on the CONTAINS topic. I've read the previous ticket and this one and please correct me if I'm wrong, but my conclusion from it is that FWD will not use the same WORD-INDEX rules as the 4GL so we will have to add a BY clause to get the sequence we had previously?
Until this ticket is resolved, yes. However, I'm not exactly sure what that needs to look like, since specifying BY <word-indexed field> is not going to have the same meaning as sorting by the words matching the CONTAINS expression. Ovidiu, Radu, any ideas for a temporary workaround here?
Radu, given the need to resolve this sooner rather than later, I'm assigning this to you, but if there is someone else on your team that you think can handle it, please feel free to re-assign.
Also, I'm clear that FWD will pick the same records as the 4GL but if it's not going to use the WORD-INDEX then is there going to be a performance issue with queries using CONTAINS in FWD? Just in 4GL terms if you're using the PRIMARY index on a table to do a 'CONTAINS' type function in a query then it will be much slower?
I don't think this should cause a performance issue. Each word-indexed field causes a separate, secondary "word table" to be created in the schema, which contains the results of parsing the words in the word-indexed column of the primary table. This secondary table is indexed by word, so this should allow the database to create as efficient a query plan as possible, given the complexity of the original query in the 4GL code.
Currently, we don't structure the ORDER BY portion of the converted query to sort by the words in that secondary table. But I think this is a matter of sorting, rather than performance. Fixing this is the focus of this ticket.
Ovidiu, Radu, please feel free to correct anything I may have misstated above.
#8 Updated by Ovidiu Maxiniuc almost 2 years ago
Eric Faulhaber wrote:
Andy Edwards wrote:
[...] FWD will not use the same WORD-INDEX rules as the 4GL so we will have to add a BY clause to get the sequence we had previously?
Until this ticket is resolved, yes. However, I'm not exactly sure what that needs to look like, since specifying
BY <word-indexed field>is not going to have the same meaning as sorting by the words matching theCONTAINSexpression. Ovidiu, Radu, any ideas for a temporary workaround here?
I do not think how a by clause would sort according to matched word in contains, as seen in #9194-3, 4th example. Sorting on a field or one element of array is possible, though.
Also, I'm clear that FWD will pick the same records as the 4GL but if it's not going to use the WORD-INDEX then is there going to be a performance issue with queries using CONTAINS in FWD? Just in 4GL terms if you're using the PRIMARY index on a table to do a 'CONTAINS' type function in a query then it will be much slower?
I don't think this should cause a performance issue. Each word-indexed field causes a separate, secondary "word table" to be created in the schema, which contains the results of parsing the words in the word-indexed column of the primary table. This secondary table is indexed by word, so this should allow the database to create as efficient a query plan as possible, given the complexity of the original query in the 4GL code.
Currently, we don't structure the ORDER BY portion of the converted query to sort by the words in that secondary table. But I think this is a matter of sorting, rather than performance. Fixing this is the focus of this ticket.
Related to Rule 3. The way CONTAINS is implemented in FWD will cause the word index to be always used. At least in the meaning FWD has for this index. It is used for looking up the word, not for sorting.
So, when talking of performance, I think FWD does the best effort: it splits the 'haystack' into words as they are flushed and index them. At the moment of the query the information is already half processed and only needs to be 'collected' and assembled. But, as this task states, the problem is the order in which the assembly is performed.
#9 Updated by Andy Edwards almost 2 years ago
OK, thank you for your response and the one previous about the projects (I hadn't been made aware of this).
#10 Updated by Radu Apetrii almost 2 years ago
I have created 9194a for further changes. First, I'll check why the word-index is not selected. After that, I'll see if the generated order by clause needs to be changed accordingly. Maybe the correct selection of the index fixes the second part, we'll see.
#11 Updated by Radu Apetrii almost 2 years ago
- File 1587.patch
added
It's time for another blast from the past (maybe?). I'm going to take all of you back to #1587 (the ticket, not the year), and I'm going to put my finger on the revision that introduced the "unselection" of word-indices: trunk rev. 12004 (same revision as in 3821c, I know, what a memorable name). I'll also attach the patch with the rev. 12004 changes for more clarity. We are facing now something that Eric has foreseen more than 3 years ago: #1587-338. For the record, it's true that uncommenting the piece of code from the patch in index_selection.rules solves the issue (the word index can be selected), but I don't think it's a complete solution. And frankly, I'm a bit afraid of what that would look like. Basically, we would have to re-enable that code, but also address the sorting scenario (taking into account extents as well). Until some new ideas come to my mind, I will let you digest this piece of information and add on it.
#12 Updated by Radu Apetrii over 1 year ago
- File word-index-test.diff
added - File word-index-sql.diff
added - File sql-trunk.sql added
- File sql-9194.sql added
- File Start-trunk.java
added - File Start-9194.java
added - File start.p
added - File fwd.df added
- A
start.pwhich contains 7 query examples written in 4GL. - A
fwd.dfwhich contains the table + index schema used.- In short terms, there's a
testtable with 4 fields:f1,f2,f3of type integer, andc1of type character. - As for indexes, there's an
idx_primarywhich is a primary unique index on fieldf1, anidx2on fieldsf2andf3, and anidx_wordwhich is a word-index on fieldc1.
- In short terms, there's a
- Two java files:
Start-trunk.javawhich represents the converted code ofstart.pwith trunk.Start-9194.javawhich is the converted code with word-indexes enabled.
- A
word-index-test.diffwhich is a diff file that highlights the differences between the two java files.- In here, the '<' symbol corresponds to the trunk version, and the '>' is for the 9194 conversion (i.e. with the word-index enabled).
- A
sql-trunk.sqlfile with the SQLs executed in the trunk version. - A
sql-9194.sqlfile with the SQLs executed in the 9194 version (with the word-index selection enabled). - A
word-index-sql.difffor highlighting the differences between the two SQL files.
I know there's quite a lot of information to process (in fact, there's more files than query examples). Maybe the most notable change was for query2, which switched from an AdaptiveQuery to a PreselectQuery. I think I'll run the same test with Hotel next.
#13 Updated by Eric Faulhaber over 1 year ago
- reviewer Eric Faulhaber added
#14 Updated by Radu Apetrii over 1 year ago
- reviewer deleted (
Eric Faulhaber)
Eric, if you want to take a look at the files, you can check both .diff files, they aren't that large. Keep in mind that the '<' symbol corresponds to the trunk version, and the '>' is for the 9194 conversion (i.e. with the word-index enabled).
#15 Updated by Radu Apetrii over 1 year ago
- reviewer Eric Faulhaber added
#16 Updated by Radu Apetrii over 1 year ago
Radu Apetrii wrote:
I think I'll run the same test with Hotel next.
Well, nothing changed in Hotel with word-index selection enabled. I will check a large customer application next.
#17 Updated by Radu Apetrii over 1 year ago
- % Done changed from 0 to 50
- Status changed from New to WIP
- I re-enabled the selection of word-indexes.
Next, we need to figure out how should the order by clause look like when a word-index is selected. I placed this at 50% because we still need to perform some changes to the order by generating phase.
#18 Updated by Greg Shah about 2 months ago
- topics Word Indexes added
#19 Updated by Radu Apetrii about 2 months ago
- version_resolved set to trunk/16593
- Status changed from WIP to Test
- % Done changed from 50 to 100
#20 Updated by Radu Apetrii about 2 months ago
- version_resolved deleted (
trunk/16593) - % Done changed from 100 to 50
- Status changed from Test to WIP
False alarm, it seems that the selected index is wrong even with the recent trunk. The discussion happened in #11448.