Project

General

Profile

Bug #9194

FWD selects the wrong index when using CONTAINS?

Added by Radu Apetrii almost 2 years ago. Updated about 2 months ago.

Status:
WIP
Priority:
High
Assignee:
Target version:
-
Start date:
Due date:
% Done:

50%

billable:
No
vendor_id:
GCD
case_num:
version_reported:
version_resolved:
production:
No
env_name:
topics:
Word Indexes

1587.patch Magnifier (2.9 KB) Radu Apetrii, 10/09/2024 10:47 AM

start.p Magnifier (524 Bytes) Radu Apetrii, 11/25/2024 06:34 AM

fwd.df (912 Bytes) Radu Apetrii, 11/25/2024 06:34 AM

Start-9194.java Magnifier (3.76 KB) Radu Apetrii, 11/25/2024 06:34 AM

Start-trunk.java Magnifier (3.76 KB) Radu Apetrii, 11/25/2024 06:34 AM

word-index-test.diff Magnifier (1.11 KB) Radu Apetrii, 11/25/2024 06:34 AM

sql-9194.sql (2.25 KB) Radu Apetrii, 11/25/2024 06:48 AM

sql-trunk.sql (2.21 KB) Radu Apetrii, 11/25/2024 06:48 AM

word-index-sql.diff Magnifier (624 Bytes) Radu Apetrii, 11/25/2024 06:48 AM

History

#1 Updated by Radu Apetrii almost 2 years ago

In #8357, it was brought to our attention that FWD selects the wrong index in a query that has the 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

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

Example 3

Then, we were interested in what is taken into consideration when sorting records from a word-index perspective.

Example 4

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):

Index Selection Rules shows that USE-INDEX (rule 1) and "unique index with all components in equality matches" (rule 2) should have preference over CONTAINS (rule 3).

Further discoveries:
  • About Rule 1: In 4GL, a query cannot have both CONTAINS and USE-INDEX. If I write such query, I get the error USE-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 WHERE clause has all the components (of a unique index) in equality matches AND a CONTAINS clause, both indexes are evaluated. The WHERE looks like word-index check AND unique index check.
    • The xref compile report shows both SEARCH fwd.test idx_word (word-index) and SEARCH 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 SEARCH statements for the AND case is always the same, despite rearranging the operands in the WHERE clause. The word-index SEARCH always appears before the unique index SEARCH in the xref report.
  • About Rule 2 part 2: If I replace the AND in the WHERE clause with an OR, so that the WHERE looks like word-index check OR unique index check, still both indexes are evaluated.
    • However, the order of SEARCH in the xref report depends on the order of operands in the WHERE clause.
      • If the where is word-index check OR unique index check, xref looks like SEARCH fwd.test idx_word (word-index) and SEARCH fwd.test idx2 (unique index).
      • If the where is unique index check OR word-index check, xref looks like SEARCH fwd.test idx2 (unique index) and SEARCH fwd.test idx_word (word-index).
  • 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 WHERE clause that has a CONTAINS and nothing else (no BY clauses, 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 the CONTAINS expression. 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

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

Soo, I can finally make an update. I will attach a couple of files:
  • A start.p which contains 7 query examples written in 4GL.
  • A fwd.df which contains the table + index schema used.
    • In short terms, there's a test table with 4 fields: f1, f2, f3 of type integer, and c1 of type character.
    • As for indexes, there's an idx_primary which is a primary unique index on field f1, an idx2 on fields f2 and f3, and an idx_word which is a word-index on field c1.
  • Two java files:
    • Start-trunk.java which represents the converted code of start.p with trunk.
    • Start-9194.java which is the converted code with word-indexes enabled.
  • A word-index-test.diff which 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.sql file with the SQLs executed in the trunk version.
  • A sql-9194.sql file with the SQLs executed in the 9194 version (with the word-index selection enabled).
  • A word-index-sql.diff for 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've committed to 9194a rev. 15578 a really small change:
  • 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.

Also available in: Atom PDF