Are you setting the constraintUsage return parameters correctly?

SQLite ist asking two questions:

1) What is the cost of a full table scan on table inventory (your answer is 
4581; I personally would leave idxNum=0 for this case)

2) What is the least cost of doing a partial table scan with any combination of 
the four constraints (resulting from the joins of t1->t2 on inventory_id and 
T4/5/6 -> t2 on film_id)

In the second case, you should not only set rows and cost, but also indicate 
which constraint is to be used e.b. by setting constraintUsage[0].argvIndex = 
1. This allows SQLite to pass the actual constraint value to the xFilter 
function.
Also, if you can guarantee that your xFilter/xNext implementation will only 
return matching rows, you should set contraintUsage[0].omit = 1. This allows 
SQLite to skip the value check that would be coded to eliminate unwanted rows.
Personally, I would be using small positive numbers for the indexes.

Again, you should not be creating Indexes in xBestIndex; if you are actually 
creating indexes on request in xFilter, the cost of doing that should be 
included in the cost return value.

Looking at your query, you will be returning the cartesian product of all 
actors and categories. I also find it strange to join inventory records to 
actors and categories instead of joining via the film table, as would be 
suggested by the n:m relational table names too.

-----Urspr?ngliche Nachricht-----
Von: Eric Hill [mailto:Eric.Hill at jmp.com]
Gesendet: Freitag, 15. Mai 2015 18:03
An: sqlite-users at mailinglists.sqlite.org
Betreff: [sqlite] Virtual Table query - why isn't SQLite using my indexes?

Hey,

Let me say up front that I'm sure this is my fault.  I have SQLite version 
3.8.9.

I am using virtual tables, and I am trying to get xBestIndex and xFilter doing 
the right things so that I get optimal queries.  Currently, I am working on the 
following query:

                SELECT t1.rental_date, t1.inventory_id, t1.customer_id, 
t2.film_id,
                                t2.store_id, t3.first_name AS cust_firstname, 
t3.last_name AS cust_lastname, t3.email,
                                t6.category_id, t4.title, t4.release_year, 
t4.length,
                                t4.rating, t4.rental_rate, t5.actor_id, t8.name 
AS category,
                                t7.first_name AS actor_firstname, t7.last_name 
AS actor_lastname
                FROM rental10  t1
                                LEFT OUTER JOIN inventory t2
                                                ON  ( t2.inventory_id = 
t1.inventory_id )
                                LEFT OUTER JOIN customer t3
                                                ON  ( t3.customer_id = 
t1.customer_id )
                                LEFT OUTER JOIN film_category t6
                                                ON  ( t6.film_id = t2.film_id )
                                LEFT OUTER JOIN film t4
                                                ON  ( t4.film_id = t2.film_id )
                                LEFT OUTER JOIN film_actor t5
                                                ON  ( t5.film_id = t2.film_id )
                                LEFT OUTER JOIN category t8
                                                ON  ( t8.category_id = 
t6.category_id )
                                LEFT OUTER JOIN actor t7
                                                ON  ( t7.actor_id = t5.actor_id 
);

When I execute this query, the result is correct, but it is taking too long by 
an order of magnitude or two.  It seems to be doing full table scans despite 
the fact that I am creating indexes as requested.

For example, xBestIndex gets called for the inventory table twice, with four 
constraints, once with usable set to false for all four constraints, and once 
with usable set to true for all four.  Here is my printf debugging spew:

jmpvtab BEST INDEX:  Table: inventory  nConstraints: 4
   CONST[0]: 0 (inventory_id) = Unusable
   CONST[1]: 1 (film_id) = Unusable
   CONST[2]: 1 (film_id) = Unusable
   CONST[3]: 1 (film_id) = Unusable
   Index NOT created: est. cost: 4581
jmpvtab BEST INDEX:  Table: inventory  nConstraints: 4
   CONST[0]: 0 (inventory_id) = Usable
   CONST[1]: 1 (film_id) = Usable
   CONST[2]: 1 (film_id) = Usable
   CONST[3]: 1 (film_id) = Usable
   Index created: est. cost: 3.66096029177608

So, in the first case, I do not create an index (which I signify by setting 
idxNum to -999), and I set the cost (and, est. rows) to 4581.  In the second 
case, I create an index (0) and set cost to log10(4581) = 3.66 and est. rows to 
4.  Yet, later, whenever xFilter is called for the inventory table, SQLite 
passes in idxNum = 999 and nConstraints = 0.  The index I dutifully created is 
never asked for.  In cases where there is a single constraint, SQLite does ask 
request the index in the xFilter call, but it seems that for all the cases 
where multiple constraints are involved, the index is not being used.

I did EXPLAIN QUERY PLAN for the query and got this, consistent with what I'm 
seeing:

0              0              0              SCAN TABLE rental10 AS t1 VIRTUAL 
TABLE INDEX -999:
0              1              1              SCAN TABLE inventory AS t2 VIRTUAL 
TABLE INDEX -999:
0              2              2              SCAN TABLE customer AS t3 VIRTUAL 
TABLE INDEX 0:
0              3              3              SCAN TABLE film_category AS t6 
VIRTUAL TABLE INDEX -999:
0              4              4              SCAN TABLE film AS t4 VIRTUAL 
TABLE INDEX 0:
0              5              5              SCAN TABLE film_actor AS t5 
VIRTUAL TABLE INDEX -999:
0              6              6              SCAN TABLE category AS t8 VIRTUAL 
TABLE INDEX -999:
0              7              7              SCAN TABLE actor AS t7 VIRTUAL 
TABLE INDEX 0:

Now, I know that SQLite is capable of efficiently performing this query, 
because I also have the ability to copy these tables into SQLite so that I am 
querying real tables instead of virtual tables.  SQLite can perform the query 
in under 1 second with real tables, but with virtual tables, it is taking > 25 
seconds.

Any thoughts on what I can do to convince SQLite to use my indexes?

Thanks,

Eric

_______________________________________________
sqlite-users mailing list
sqlite-users at mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


___________________________________________
 Gunter Hick
Software Engineer
Scientific Games International GmbH
FN 157284 a, HG Wien
Klitschgasse 2-4, A-1130 Vienna, Austria
Tel: +43 1 80100 0
E-Mail: hick at scigames.at

This communication (including any attachments) is intended for the use of the 
intended recipient(s) only and may contain information that is confidential, 
privileged or legally protected. Any unauthorized use or dissemination of this 
communication is strictly prohibited. If you have received this communication 
in error, please immediately notify the sender by return e-mail message and 
delete all copies of the original communication. Thank you for your cooperation.


Reply via email to