tested with sqlite-3.7.3
Hello, I'm trying to use the collations with BLOB because I am sorting something else that text. For example I have some types which can not be used as-is with SQLite because these types can be more complex. Then I have a collation which provides the right order. But my tables have millions of BLOB to sort and without indexes it is very very slow. I'm trying to use an index + collation with my BLOBs but there is something strange. It seems that my index on the collation is not used accordingly to EXPLAIN QUERY PLAN. But it seems that the callback for the comparison is not called then is suggests that the index is used. I've made a small program with this output (please, look at the attached C code _first_): insert into tmp ................. insert into lol step for first query 0 | 1 : TABLE tmp WITH INDEX idx_foobar ORDER BY 1 | 0 : TABLE tmp USING PRIMARY KEY step for second query 0 | 0 : TABLE lol 1 | 1 : TABLE tmp USING PRIMARY KEY There are two queries. Both provide the same output but the second uses ID from the table 'lol' for an INNER JOIN with the table tmp. The first query is stupid (it uses the tmp table with the JOIN on itself). It is just an example. A dot [.] is printed every time that the collation is computing a comparison. In the case, the comparisons are done with the INSERTs. My question: Why EXPLAIN QUERY PLAN does not show idx_foobar in the second query? Is the index used? It seems that this index is used, because otherwise more dot [.] should be printed between "step for first " and "step for second ". No? Thanks Regards, Mathieu SCHROETER
#include <stdio.h> #include <string.h> #include "sqlite3.h" static int cmp (void *data, int len1, const void *d1, int len2, const void *d2) { printf ("."); return -memcmp (d1, d2, 4); } int main (void) { sqlite3 *db; sqlite3_stmt *stmt; char *err = NULL; unlink ("./tmp.db"); sqlite3_open ("./tmp.db", &db); sqlite3_create_collation (db, "foobar", SQLITE_UTF8, NULL, cmp); sqlite3_exec (db, "CREATE TABLE tmp (id INTEGER PRIMARY KEY AUTOINCREMENT, data BLOB);" "CREATE TABLE lol (id INTEGER);" "CREATE INDEX idx_foobar ON tmp (data COLLATE foobar);", NULL, NULL, &err); printf ("insert into tmp\n"); sqlite3_exec (db, "INSERT INTO tmp (data) values (CAST(x'0100' AS TEXT));" "INSERT INTO tmp (data) values (CAST(x'0400' AS TEXT));" "INSERT INTO tmp (data) values (CAST(x'0050' AS TEXT));" "INSERT INTO tmp (data) values (CAST(x'1800' AS TEXT));" "INSERT INTO tmp (data) values (CAST(x'0090' AS TEXT));" "INSERT INTO tmp (data) values (CAST(x'0105' AS TEXT));" "INSERT INTO tmp (data) values (CAST(x'0000' AS TEXT));" "INSERT INTO tmp (data) values (CAST(x'0001' AS TEXT));", NULL, NULL, &err); printf ("\ninsert into lol\n"); sqlite3_exec (db, "INSERT INTO lol (id) values (1);" "INSERT INTO lol (id) values (2);" "INSERT INTO lol (id) values (3);" "INSERT INTO lol (id) values (4);" "INSERT INTO lol (id) values (5);" "INSERT INTO lol (id) values (6);" "INSERT INTO lol (id) values (7);" "INSERT INTO lol (id) values (8);", NULL, NULL, &err); if (err) { fprintf (stderr, "%s\n", err); sqlite3_free (err); goto out; } sqlite3_prepare_v2 (db, "EXPLAIN QUERY PLAN " "SELECT data " "FROM (" "SELECT id AS id0 " "FROM tmp " ") INNER JOIN tmp " "ON id0 = tmp.id " "ORDER BY data COLLATE foobar;", -1, &stmt, NULL); printf ("step for first query\n"); /*while (sqlite3_step (stmt) == SQLITE_ROW) printf ("%10s | %10s : %s\n", sqlite3_column_text (stmt, 0), sqlite3_column_text (stmt, 1), sqlite3_column_text (stmt, 2));*/ //sqlite3_finalize (stmt); printf ("\nstep for second query\n"); sqlite3_prepare_v2 (db, "EXPLAIN QUERY PLAN " "SELECT data " "FROM (" "SELECT id AS id0 " "FROM lol " ") INNER JOIN tmp " "ON id0 = tmp.id " "ORDER BY data COLLATE foobar;", -1, &stmt, NULL); while (sqlite3_step (stmt) == SQLITE_ROW) printf ("%10s | %10s : %s\n", sqlite3_column_text (stmt, 0), sqlite3_column_text (stmt, 1), sqlite3_column_text (stmt, 2)); sqlite3_finalize (stmt); sqlite3_close (db); out: unlink ("./tmp.db"); return 0; }
_______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users